const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const Database = require('better-sqlite3');
const path = require('path');
const fs = require('fs');
const multer = require('multer');
require('dotenv').config();

const app = express();
const PORT = process.env.PORT || 3001;
const DB_DIR = path.join(__dirname, 'database');
const DB_PATH = path.join(DB_DIR, 'gardentrack.db');

// Ensure uploads directory exists
const UPLOADS_DIR = path.join(__dirname, 'uploads');
if (!fs.existsSync(UPLOADS_DIR)) {
  fs.mkdirSync(UPLOADS_DIR, { recursive: true });
  console.log('Created uploads directory');
}

// Ensure database directory exists
if (!fs.existsSync(DB_DIR)) {
  fs.mkdirSync(DB_DIR, { recursive: true });
  console.log('Created database directory');
}

// Middleware
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// Serve uploaded files statically
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

// Configure multer for file uploads
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, UPLOADS_DIR);
  },
  filename: function (req, file, cb) {
    // Generate unique filename with timestamp
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    const extension = path.extname(file.originalname);
    cb(null, 'plant-' + uniqueSuffix + extension);
  }
});

const fileFilter = (req, file, cb) => {
  // Accept only image files
  if (file.mimetype.startsWith('image/')) {
    cb(null, true);
  } else {
    cb(new Error('Only image files are allowed!'), false);
  }
};

const upload = multer({ 
  storage: storage,
  fileFilter: fileFilter,
  limits: {
    fileSize: 5 * 1024 * 1024 // 5MB limit
  }
});

// Database connection and initialization
let db;
try {
  db = new Database(DB_PATH);
  console.log('Connected to SQLite database at:', DB_PATH);
  initializeDatabase();
} catch (err) {
  console.error('Error opening database:', err.message);
  process.exit(1);
}

// Initialize database tables
function initializeDatabase() {
  console.log('Initializing database tables...');
  
  try {
    // Plants table
    db.exec(`
      CREATE TABLE IF NOT EXISTS plants (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        type TEXT NOT NULL,
        variety TEXT NOT NULL,
        purchase_location TEXT NOT NULL,
        seedling_age INTEGER NOT NULL,
        seedling_height REAL NOT NULL,
        planting_date DATE NOT NULL,
        health_status TEXT DEFAULT 'good' CHECK(health_status IN ('good', 'needs-attention', 'dead')),
        current_height REAL,
        photo_url TEXT,
        current_photo_url TEXT,
        estimated_ripening_start INTEGER,
        estimated_ripening_end INTEGER,
        ripening_notes TEXT,
        notes TEXT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
      )
    `);
    console.log('Plants table ready');

    // Fertilizers table
    db.exec(`
      CREATE TABLE IF NOT EXISTS fertilizers (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        brand TEXT,
        type TEXT NOT NULL CHECK(type IN ('organic', 'synthetic', 'liquid', 'granular', 'slow-release')),
        npk_ratio TEXT,
        description TEXT,
        application_rate TEXT,
        frequency TEXT,
        season TEXT,
        notes TEXT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
      )
    `);
    console.log('Fertilizers table ready');

    // Chemicals table
    db.exec(`
      CREATE TABLE IF NOT EXISTS chemicals (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        brand TEXT,
        type TEXT NOT NULL CHECK(type IN ('pesticide', 'herbicide', 'fungicide', 'insecticide', 'miticide')),
        active_ingredient TEXT,
        concentration TEXT,
        target_pests TEXT,
        application_method TEXT,
        safety_period INTEGER,
        notes TEXT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
      )
    `);
    console.log('Chemicals table ready');

    // Plant observations table
    db.exec(`
      CREATE TABLE IF NOT EXISTS plant_observations (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        plant_id INTEGER NOT NULL,
        date DATE NOT NULL,
        title TEXT NOT NULL,
        observation TEXT NOT NULL,
        weather_conditions TEXT,
        temperature REAL,
        photo_url TEXT,
        tags TEXT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (plant_id) REFERENCES plants (id) ON DELETE CASCADE
      )
    `);
    console.log('Plant observations table ready');

    // Harvest processing table
    db.exec(`
      CREATE TABLE IF NOT EXISTS harvest_processing (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        harvest_id INTEGER NOT NULL,
        process_type TEXT NOT NULL CHECK(process_type IN ('fresh', 'frozen', 'jam', 'dried', 'canned', 'juice', 'sauce', 'pickled', 'other')),
        quantity REAL NOT NULL,
        unit TEXT NOT NULL,
        process_date DATE NOT NULL,
        expiry_date DATE,
        storage_location TEXT,
        notes TEXT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (harvest_id) REFERENCES harvest_records (id) ON DELETE CASCADE
      )
    `);
    console.log('Harvest processing table ready');

    // Harvest stock table
    db.exec(`
      CREATE TABLE IF NOT EXISTS harvest_stock (
       id INTEGER PRIMARY KEY AUTOINCREMENT,
       processing_id INTEGER NOT NULL,
       current_quantity REAL NOT NULL,
       unit TEXT NOT NULL,
       last_updated DATE NOT NULL,
       status TEXT DEFAULT 'available' CHECK(status IN ('available', 'consumed', 'expired', 'spoiled')),
       notes TEXT,
       created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
       updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
       FOREIGN KEY (processing_id) REFERENCES harvest_processing (id) ON DELETE CASCADE
      )
    `);
    console.log('Harvest stock table ready');

    // Plant history table
    db.exec(`
      CREATE TABLE IF NOT EXISTS plant_history (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        plant_id INTEGER NOT NULL,
        year INTEGER NOT NULL,
        blooming_date DATE,
        fruiting_date DATE,
        harvest_date DATE,
        current_height REAL,
        current_photo_url TEXT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (plant_id) REFERENCES plants (id) ON DELETE CASCADE
      )
    `);
    console.log('Plant history table ready');

    // Harvest records table
    db.exec(`
      CREATE TABLE IF NOT EXISTS harvest_records (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        plant_id INTEGER NOT NULL,
        date DATE NOT NULL,
        quantity REAL NOT NULL,
        unit TEXT NOT NULL,
        weight REAL,
        weight_unit TEXT,
        notes TEXT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (plant_id) REFERENCES plants (id) ON DELETE CASCADE
      )
    `);
    console.log('Harvest records table ready');

    // Maintenance records table
    db.exec(`
      CREATE TABLE IF NOT EXISTS maintenance_records (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        plant_id INTEGER NOT NULL,
        date DATE NOT NULL,
        type TEXT NOT NULL CHECK(type IN ('chemical', 'fertilizer', 'watering', 'pruning', 'transplanting', 'other')),
        description TEXT NOT NULL,
        amount TEXT,
        fertilizer_id INTEGER,
        chemical_id INTEGER,
        is_planned BOOLEAN DEFAULT 0,
        is_completed BOOLEAN DEFAULT 1,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (plant_id) REFERENCES plants (id) ON DELETE CASCADE,
        FOREIGN KEY (fertilizer_id) REFERENCES fertilizers (id) ON DELETE SET NULL,
        FOREIGN KEY (chemical_id) REFERENCES chemicals (id) ON DELETE SET NULL
      )
    `);
    console.log('Maintenance records table ready');

    // Tasks table
    db.exec(`
      CREATE TABLE IF NOT EXISTS tasks (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        plant_id INTEGER,
        type TEXT DEFAULT 'general' CHECK(type IN ('general', 'fertilizer', 'chemical', 'watering', 'pruning', 'transplanting', 'harvesting', 'other')),
        title TEXT NOT NULL,
        description TEXT,
        deadline DATE NOT NULL,
        completed BOOLEAN DEFAULT 0,
        fertilizer_id INTEGER,
        chemical_id INTEGER,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (plant_id) REFERENCES plants (id) ON DELETE SET NULL,
        FOREIGN KEY (fertilizer_id) REFERENCES fertilizers (id) ON DELETE SET NULL,
        FOREIGN KEY (chemical_id) REFERENCES chemicals (id) ON DELETE SET NULL
      )
    `);
    console.log('Tasks table ready');

    // Insert sample data if tables are empty
    const plantCount = db.prepare('SELECT COUNT(*) as count FROM plants').get();
    
    if (plantCount.count === 0) {
      console.log('Inserting sample data...');
      insertSampleData();
    } else {
      console.log('Database already contains data');
    }
  } catch (err) {
    console.error('Error initializing database:', err);
    process.exit(1);
  }
}

// Insert sample data
function insertSampleData() {
  try {
    // Sample fertilizers
    const insertFertilizer = db.prepare(`
      INSERT INTO fertilizers (name, brand, type, npk_ratio, description, application_rate, frequency, season, notes) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    `);
    
    insertFertilizer.run('All-Purpose Garden Fertilizer', 'Miracle-Gro', 'synthetic', '10-10-10', 'Balanced fertilizer for general garden use', '1 tablespoon per gallon', 'Every 2 weeks', 'Spring-Summer', 'Good for most plants');
    insertFertilizer.run('Organic Compost', 'Local Farm', 'organic', '3-2-2', 'Natural organic matter for soil improvement', '2-3 inches layer', 'Twice yearly', 'Spring-Fall', 'Improves soil structure');
    insertFertilizer.run('Bone Meal', 'Espoma', 'organic', '3-15-0', 'Slow-release phosphorus for root development', '1-2 tablespoons per plant', 'Once per season', 'Spring', 'Great for flowering plants');
    insertFertilizer.run('Liquid Kelp', 'Neptune\'s Harvest', 'liquid', '0-0-1', 'Seaweed extract for plant health', '1 tablespoon per gallon', 'Monthly', 'All seasons', 'Boosts plant immunity');

    // Sample chemicals
    const insertChemical = db.prepare(`
      INSERT INTO chemicals (name, brand, type, active_ingredient, concentration, target_pests, application_method, safety_period, notes) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    `);
    
    insertChemical.run('Neem Oil', 'Garden Safe', 'insecticide', 'Azadirachtin', '0.9%', 'Aphids, whiteflies, spider mites', 'Foliar spray', 1, 'Organic option, safe for beneficial insects');
    insertChemical.run('Copper Fungicide', 'Bonide', 'fungicide', 'Copper sulfate', '8%', 'Blight, rust, mildew', 'Foliar spray', 7, 'Use in early morning or evening');
    insertChemical.run('Bt Spray', 'Safer Brand', 'pesticide', 'Bacillus thuringiensis', '0.5%', 'Caterpillars, larvae', 'Foliar spray', 0, 'Organic, targets specific pests');
    insertChemical.run('Systemic Insecticide', 'Bayer', 'insecticide', 'Imidacloprid', '1.47%', 'Aphids, scale, thrips', 'Soil drench', 21, 'Long-lasting protection');

    // Sample plants
    const insertPlant = db.prepare(`
      INSERT INTO plants (type, variety, purchase_location, seedling_age, seedling_height, planting_date, health_status, current_height, notes) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    `);
    
    insertPlant.run('tree', 'Apple - Honeycrisp', 'Local Nursery', 12, 45.5, '2022-04-15', 'good', 180.2, 'Growing well, good fruit production');
    insertPlant.run('shrub', 'Blueberry - Bluecrop', 'Garden Center', 8, 25.0, '2023-03-20', 'needs-attention', 65.8, 'Leaves showing slight discoloration');
    insertPlant.run('herb', 'Basil - Sweet Genovese', 'Online Store', 3, 8.2, '2024-05-10', 'good', 22.5, 'Producing well, regular harvests');

    // Sample tasks
    const insertTask = db.prepare(`
      INSERT INTO tasks (plant_id, title, description, deadline, completed) 
      VALUES (?, ?, ?, ?, ?)
    `);
    
    insertTask.run(1, 'Apply fertilizer', 'Apply spring fertilizer to apple trees', '2024-03-15', 0);
    insertTask.run(2, 'Prune blueberry bushes', 'Annual pruning before spring growth', '2024-02-28', 1);
    insertTask.run(3, 'Harvest basil', 'Regular harvest to encourage growth', '2024-06-01', 0);

    // Sample maintenance records
    const insertMaintenance = db.prepare(`
      INSERT INTO maintenance_records (plant_id, date, type, description, amount, fertilizer_id, chemical_id, is_planned, is_completed) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    `);
    
    insertMaintenance.run(1, '2024-01-10', 'pruning', 'Winter pruning - removed dead branches', null, null, null, 0, 1);
    insertMaintenance.run(2, '2024-01-05', 'fertilizer', 'Applied organic compost', '2 cups', 2, null, 0, 1);
    insertMaintenance.run(3, '2024-05-15', 'watering', 'Deep watering during dry spell', '1 gallon', null, null, 0, 1);
    insertMaintenance.run(1, '2024-03-20', 'chemical', 'Applied neem oil for aphid prevention', '2 tablespoons per gallon', null, 1, 0, 1);

    // Sample harvest records
    const insertHarvest = db.prepare(`
      INSERT INTO harvest_records (plant_id, date, quantity, unit, notes) 
      VALUES (?, ?, ?, ?, ?)
    `);
    
    insertHarvest.run(1, '2023-09-15', 25, 'lbs', 'Excellent harvest, apples were sweet and crisp');
    insertHarvest.run(2, '2023-07-20', 3, 'cups', 'First harvest of the season, berries were plump and sweet');
    insertHarvest.run(3, '2024-05-25', 0.5, 'cups', 'Fresh basil for cooking, very aromatic');

    // Sample observations
    const insertObservation = db.prepare(`
      INSERT INTO plant_observations (plant_id, date, title, observation, weather_conditions, temperature, tags) 
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `);
    
    insertObservation.run(1, '2024-01-15', 'Winter dormancy check', 'Apple tree showing normal winter dormancy. Buds are tight and healthy looking. No signs of pest damage on bark.', 'Clear, cold', 2.5, 'dormancy,health-check,winter');
    insertObservation.run(2, '2024-01-20', 'Pruning completed', 'Finished annual pruning of blueberry bushes. Removed about 20% of old wood and opened up center for better air circulation.', 'Overcast', 8.0, 'pruning,maintenance');
    insertObservation.run(3, '2024-05-12', 'First true leaves', 'Basil seedlings showing first set of true leaves. Growth is vigorous and color is deep green. Ready for transplanting soon.', 'Sunny', 22.0, 'growth,seedling,transplant-ready');
    console.log('Sample data inserted successfully!');
  } catch (err) {
    console.error('Error inserting sample data:', err);
  }
}

// Routes

// Photo upload endpoint
app.post('/api/upload-photo', upload.single('photo'), (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ error: 'No file uploaded' });
    }
    
    // Return the file path relative to the server
    const photoUrl = `/uploads/${req.file.filename}`;
    res.json({ photoUrl });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Plant Observations
app.get('/api/observations', (req, res) => {
  try {
    const stmt = db.prepare('SELECT * FROM plant_observations ORDER BY date DESC');
    const rows = stmt.all();
    
    res.json(rows.map(row => ({
      id: row.id,
      plantId: row.plant_id,
      date: row.date,
      title: row.title,
      observation: row.observation,
      weatherConditions: row.weather_conditions,
      temperature: row.temperature,
      photoUrl: row.photo_url,
      tags: row.tags,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.post('/api/observations', (req, res) => {
  try {
    const { plantId, date, title, observation, weatherConditions, temperature, photoUrl, tags } = req.body;
    
    const stmt = db.prepare(`
      INSERT INTO plant_observations (plant_id, date, title, observation, weather_conditions, temperature, photo_url, tags) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    `);
    
    const result = stmt.run(plantId, date, title, observation, weatherConditions, temperature, photoUrl, tags);
    
    const getStmt = db.prepare('SELECT * FROM plant_observations WHERE id = ?');
    const row = getStmt.get(result.lastInsertRowid);
    
    res.json({
      id: row.id,
      plantId: row.plant_id,
      date: row.date,
      title: row.title,
      observation: row.observation,
      weatherConditions: row.weather_conditions,
      temperature: row.temperature,
      photoUrl: row.photo_url,
      tags: row.tags,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

app.put('/api/observations/:id', (req, res) => {
  try {
    const { plantId, date, title, observation, weatherConditions, temperature, photoUrl, tags } = req.body;
    
    const stmt = db.prepare(`
      UPDATE plant_observations SET plant_id = ?, date = ?, title = ?, observation = ?, 
      weather_conditions = ?, temperature = ?, photo_url = ?, tags = ?, updated_at = CURRENT_TIMESTAMP 
      WHERE id = ?
    `);
    
    stmt.run(plantId, date, title, observation, weatherConditions, temperature, photoUrl, tags, req.params.id);
    
    const getStmt = db.prepare('SELECT * FROM plant_observations WHERE id = ?');
    const row = getStmt.get(req.params.id);
    
    res.json({
      id: row.id,
      plantId: row.plant_id,
      date: row.date,
      title: row.title,
      observation: row.observation,
      weatherConditions: row.weather_conditions,
      temperature: row.temperature,
      photoUrl: row.photo_url,
      tags: row.tags,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

app.delete('/api/observations/:id', (req, res) => {
  try {
    const stmt = db.prepare('DELETE FROM plant_observations WHERE id = ?');
    stmt.run(req.params.id);
    res.json({ message: 'Observation deleted successfully' });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// Plants
app.get('/api/plants', (req, res) => {
  try {
    const stmt = db.prepare('SELECT * FROM plants ORDER BY created_at DESC');
    const rows = stmt.all();
    
    res.json(rows.map(row => ({
      id: row.id,
      type: row.type,
      variety: row.variety,
      purchaseLocation: row.purchase_location,
      seedlingAge: row.seedling_age,
      seedlingHeight: row.seedling_height,
      plantingDate: row.planting_date,
      healthStatus: row.health_status,
      currentHeight: row.current_height,
      photoUrl: row.photo_url,
      currentPhotoUrl: row.current_photo_url,
      estimatedRipeningStart: row.estimated_ripening_start,
      estimatedRipeningEnd: row.estimated_ripening_end,
      ripeningNotes: row.ripening_notes,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.post('/api/plants', (req, res) => {
  try {
    const { type, variety, purchaseLocation, seedlingAge, seedlingHeight, plantingDate, healthStatus, currentHeight, photoUrl, notes } = req.body;
    
    const stmt = db.prepare(`
      INSERT INTO plants (type, variety, purchase_location, seedling_age, seedling_height, planting_date, health_status, current_height, photo_url, notes) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `);
    
    const result = stmt.run(type, variety, purchaseLocation, seedlingAge, seedlingHeight, plantingDate, healthStatus, currentHeight, photoUrl, notes);
    
    // Get the created plant
    const getStmt = db.prepare('SELECT * FROM plants WHERE id = ?');
    const row = getStmt.get(result.lastInsertRowid);
    
    res.json({
      id: row.id,
      type: row.type,
      variety: row.variety,
      purchaseLocation: row.purchase_location,
      seedlingAge: row.seedling_age,
      seedlingHeight: row.seedling_height,
      plantingDate: row.planting_date,
      healthStatus: row.health_status,
      currentHeight: row.current_height,
      photoUrl: row.photo_url,
      currentPhotoUrl: row.current_photo_url,
      estimatedRipeningStart: row.estimated_ripening_start,
      estimatedRipeningEnd: row.estimated_ripening_end,
      ripeningNotes: row.ripening_notes,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

app.put('/api/plants/:id', (req, res) => {
  try {
    const { type, variety, purchaseLocation, seedlingAge, seedlingHeight, plantingDate, healthStatus, currentHeight, photoUrl, notes } = req.body;
    
    const stmt = db.prepare(`
      UPDATE plants SET type = ?, variety = ?, purchase_location = ?, seedling_age = ?, seedling_height = ?, planting_date = ?, 
      health_status = ?, current_height = ?, photo_url = ?, notes = ?, updated_at = CURRENT_TIMESTAMP 
      WHERE id = ?
    `);
    
    stmt.run(type, variety, purchaseLocation, seedlingAge, seedlingHeight, plantingDate, healthStatus, currentHeight, photoUrl, notes, req.params.id);
    
    // Get the updated plant
    const getStmt = db.prepare('SELECT * FROM plants WHERE id = ?');
    const row = getStmt.get(req.params.id);
    
    res.json({
      id: row.id,
      type: row.type,
      variety: row.variety,
      purchaseLocation: row.purchase_location,
      seedlingAge: row.seedling_age,
      seedlingHeight: row.seedling_height,
      plantingDate: row.planting_date,
      healthStatus: row.health_status,
      currentHeight: row.current_height,
      photoUrl: row.photo_url,
      currentPhotoUrl: row.current_photo_url,
      estimatedRipeningStart: row.estimated_ripening_start,
      estimatedRipeningEnd: row.estimated_ripening_end,
      ripeningNotes: row.ripening_notes,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

app.delete('/api/plants/:id', (req, res) => {
  try {
    const stmt = db.prepare('DELETE FROM plants WHERE id = ?');
    stmt.run(req.params.id);
    res.json({ message: 'Plant deleted successfully' });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// Tasks
app.get('/api/tasks', (req, res) => {
  try {
    const stmt = db.prepare(`
      SELECT t.*, f.name as fertilizer_name, c.name as chemical_name 
      FROM tasks t
      LEFT JOIN fertilizers f ON t.fertilizer_id = f.id
      LEFT JOIN chemicals c ON t.chemical_id = c.id
      ORDER BY t.deadline ASC
    `);
    const rows = stmt.all();
    
    res.json(rows.map(row => ({
      id: row.id,
      plantId: row.plant_id,
      type: row.type,
      title: row.title,
      description: row.description,
      deadline: row.deadline,
      completed: Boolean(row.completed),
      fertilizerId: row.fertilizer_id,
      chemicalId: row.chemical_id,
      fertilizerName: row.fertilizer_name,
      chemicalName: row.chemical_name,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.post('/api/tasks', (req, res) => {
  try {
    const { plantId, type, title, description, deadline, completed = false, fertilizerId, chemicalId } = req.body;
    
    const stmt = db.prepare(`
      INSERT INTO tasks (plant_id, type, title, description, deadline, completed, fertilizer_id, chemical_id) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    `);
    
    const result = stmt.run(plantId, type, title, description, deadline, completed ? 1 : 0, fertilizerId || null, chemicalId || null);
    
    const getStmt = db.prepare(`
      SELECT t.*, f.name as fertilizer_name, c.name as chemical_name 
      FROM tasks t
      LEFT JOIN fertilizers f ON t.fertilizer_id = f.id
      LEFT JOIN chemicals c ON t.chemical_id = c.id
      WHERE t.id = ?
    `);
    const row = getStmt.get(result.lastInsertRowid);
    
    res.json({
      id: row.id,
      plantId: row.plant_id,
      type: row.type,
      title: row.title,
      description: row.description,
      deadline: row.deadline,
      completed: Boolean(row.completed),
      fertilizerId: row.fertilizer_id,
      chemicalId: row.chemical_id,
      fertilizerName: row.fertilizer_name,
      chemicalName: row.chemical_name,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

app.put('/api/tasks/:id', (req, res) => {
  try {
    const { plantId, type, title, description, deadline, completed, fertilizerId, chemicalId } = req.body;
    
    const stmt = db.prepare(`
      UPDATE tasks SET plant_id = ?, type = ?, title = ?, description = ?, 
      deadline = ?, completed = ?, fertilizer_id = ?, chemical_id = ?, updated_at = CURRENT_TIMESTAMP 
      WHERE id = ?
    `);
    
    stmt.run(plantId, type, title, description, deadline, completed ? 1 : 0, fertilizerId || null, chemicalId || null, req.params.id);
    
    const getStmt = db.prepare(`
      SELECT t.*, f.name as fertilizer_name, c.name as chemical_name 
      FROM tasks t
      LEFT JOIN fertilizers f ON t.fertilizer_id = f.id
      LEFT JOIN chemicals c ON t.chemical_id = c.id
      WHERE t.id = ?
    `);
    const row = getStmt.get(req.params.id);
    
    res.json({
      id: row.id,
      plantId: row.plant_id,
      type: row.type,
      title: row.title,
      description: row.description,
      deadline: row.deadline,
      completed: Boolean(row.completed),
      fertilizerId: row.fertilizer_id,
      chemicalId: row.chemical_id,
      fertilizerName: row.fertilizer_name,
      chemicalName: row.chemical_name,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

app.delete('/api/tasks/:id', (req, res) => {
  try {
    const stmt = db.prepare('DELETE FROM tasks WHERE id = ?');
    stmt.run(req.params.id);
    res.json({ message: 'Task deleted successfully' });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// Maintenance Records
app.get('/api/maintenance', (req, res) => {
  try {
    const stmt = db.prepare(`
      SELECT mr.*, f.name as fertilizer_name, c.name as chemical_name 
      FROM maintenance_records mr
      LEFT JOIN fertilizers f ON mr.fertilizer_id = f.id
      LEFT JOIN chemicals c ON mr.chemical_id = c.id
      ORDER BY mr.date DESC
    `);
    const rows = stmt.all();
    
    res.json(rows.map(row => ({
      id: row.id,
      plantId: row.plant_id,
      date: row.date,
      type: row.type,
      description: row.description,
      amount: row.amount,
      fertilizerId: row.fertilizer_id,
      chemicalId: row.chemical_id,
      fertilizerName: row.fertilizer_name,
      chemicalName: row.chemical_name,
      isPlanned: Boolean(row.is_planned),
      isCompleted: Boolean(row.is_completed),
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.post('/api/maintenance', (req, res) => {
  try {
    const { plantId, date, type, description, amount, fertilizerId, chemicalId, isPlanned, isCompleted } = req.body;
    
    const stmt = db.prepare(`
      INSERT INTO maintenance_records (plant_id, date, type, description, amount, fertilizer_id, chemical_id, is_planned, is_completed) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    `);
    
    const result = stmt.run(plantId, date, type, description, amount, fertilizerId || null, chemicalId || null, isPlanned ? 1 : 0, isCompleted ? 1 : 0);
    
    const getStmt = db.prepare(`
      SELECT mr.*, f.name as fertilizer_name, c.name as chemical_name 
      FROM maintenance_records mr
      LEFT JOIN fertilizers f ON mr.fertilizer_id = f.id
      LEFT JOIN chemicals c ON mr.chemical_id = c.id
      WHERE mr.id = ?
    `);
    const row = getStmt.get(result.lastInsertRowid);
    
    res.json({
      id: row.id,
      plantId: row.plant_id,
      date: row.date,
      type: row.type,
      description: row.description,
      amount: row.amount,
      fertilizerId: row.fertilizer_id,
      chemicalId: row.chemical_id,
      fertilizerName: row.fertilizer_name,
      chemicalName: row.chemical_name,
      isPlanned: Boolean(row.is_planned),
      isCompleted: Boolean(row.is_completed),
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

// Harvest Records
app.get('/api/harvests', (req, res) => {
  try {
    const stmt = db.prepare('SELECT * FROM harvest_records ORDER BY date DESC');
    const rows = stmt.all();
    
    res.json(rows.map(row => ({
      id: row.id,
      plantId: row.plant_id,
      date: row.date,
      quantity: row.quantity,
      unit: row.unit,
      weight: row.weight,
      weightUnit: row.weight_unit,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.post('/api/harvests', (req, res) => {
  try {
    const { plantId, date, quantity, unit, weight, weightUnit, notes } = req.body;

    const stmt = db.prepare(`
      INSERT INTO harvest_records (plant_id, date, quantity, unit, weight, weight_unit, notes)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `);

    const result = stmt.run(plantId, date, quantity, unit, weight || null, weightUnit || null, notes);
    
    const getStmt = db.prepare('SELECT * FROM harvest_records WHERE id = ? ORDER BY date DESC');
    const row = getStmt.get(result.lastInsertRowid);
    
    res.json({
      id: row.id,
      plantId: row.plant_id,
      date: row.date,
      quantity: row.quantity,
      unit: row.unit,
      weight: row.weight,
      weightUnit: row.weight_unit,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

// Harvest Processing
app.get('/api/harvest-processing', (req, res) => {
  try {
    const stmt = db.prepare(`
      SELECT hp.*, hr.plant_id, hr.date as harvest_date 
      FROM harvest_processing hp
      JOIN harvest_records hr ON hp.harvest_id = hr.id
      ORDER BY hp.process_date DESC
    `);
    const rows = stmt.all();

    res.json(rows.map(row => ({
      id: row.id,
      harvestId: row.harvest_id,
      plantId: row.plant_id,
      harvestDate: row.harvest_date,
      processType: row.process_type,
      quantity: row.quantity,
      unit: row.unit,
      processDate: row.process_date,
      expiryDate: row.expiry_date,
      storageLocation: row.storage_location,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.post('/api/harvest-processing', (req, res) => {
  try {
    const { harvestId, processType, quantity, unit, processDate, expiryDate, storageLocation, notes } = req.body;

    const stmt = db.prepare(`
      INSERT INTO harvest_processing (harvest_id, process_type, quantity, unit, process_date, expiry_date, storage_location, notes) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    `);

    const result = stmt.run(harvestId, processType, quantity, unit, processDate, expiryDate, storageLocation, notes);

    // Create corresponding stock entry
    const stockStmt = db.prepare(`
      INSERT INTO harvest_stock (processing_id, current_quantity, unit, last_updated, status) 
      VALUES (?, ?, ?, ?, 'available')
    `);
    stockStmt.run(result.lastInsertRowid, quantity, unit, processDate);

    const getStmt = db.prepare(`
      SELECT hp.*, hr.plant_id, hr.date as harvest_date 
      FROM harvest_processing hp
      JOIN harvest_records hr ON hp.harvest_id = hr.id
      WHERE hp.id = ?
    `);
    const row = getStmt.get(result.lastInsertRowid);

    res.json({
      id: row.id,
      harvestId: row.harvest_id,
      plantId: row.plant_id,
      harvestDate: row.harvest_date,
      processType: row.process_type,
      quantity: row.quantity,
      unit: row.unit,
      processDate: row.process_date,
      expiryDate: row.expiry_date,
      storageLocation: row.storage_location,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

// Harvest Stock
app.get('/api/harvest-stock', (req, res) => {
  try {
    const stmt = db.prepare(`
      SELECT hs.*, hp.process_type, hp.harvest_id, hr.plant_id, hr.date as harvest_date 
      FROM harvest_stock hs
      JOIN harvest_processing hp ON hs.processing_id = hp.id
      JOIN harvest_records hr ON hp.harvest_id = hr.id
      ORDER BY hs.last_updated DESC
    `);
    const rows = stmt.all();

    res.json(rows.map(row => ({
      id: row.id,
      processingId: row.processing_id,
      harvestId: row.harvest_id,
      plantId: row.plant_id,
      harvestDate: row.harvest_date,
      processType: row.process_type,
      currentQuantity: row.current_quantity,
      unit: row.unit,
      lastUpdated: row.last_updated,
      status: row.status,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.put('/api/harvest-stock/:id', (req, res) => {
  try {
    const { currentQuantity, status, notes } = req.body;

    const stmt = db.prepare(`
      UPDATE harvest_stock SET current_quantity = ?, status = ?, notes = ?, 
      last_updated = date('now'), updated_at = CURRENT_TIMESTAMP 
      WHERE id = ?
    `);

    stmt.run(currentQuantity, status, notes, req.params.id);

    const getStmt = db.prepare(`
      SELECT hs.*, hp.process_type, hp.harvest_id, hr.plant_id, hr.date as harvest_date 
      FROM harvest_stock hs
      JOIN harvest_processing hp ON hs.processing_id = hp.id
      JOIN harvest_records hr ON hp.harvest_id = hr.id
      WHERE hs.id = ?
    `);
    const row = getStmt.get(req.params.id);

    res.json({
      id: row.id,
      processingId: row.processing_id,
      harvestId: row.harvest_id,
      plantId: row.plant_id,
      harvestDate: row.harvest_date,
      processType: row.process_type,
      currentQuantity: row.current_quantity,
      unit: row.unit,
      lastUpdated: row.last_updated,
      status: row.status,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

// Health check
app.get('/api/health', (req, res) => {
  res.json({ status: 'OK', message: 'GardenTrack API is running' });
});

// Fertilizers
app.get('/api/fertilizers', (req, res) => {
  try {
    const stmt = db.prepare('SELECT * FROM fertilizers ORDER BY name ASC');
    const rows = stmt.all();
    
    res.json(rows.map(row => ({
      id: row.id,
      name: row.name,
      brand: row.brand,
      type: row.type,
      npkRatio: row.npk_ratio,
      description: row.description,
      applicationRate: row.application_rate,
      frequency: row.frequency,
      season: row.season,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.post('/api/fertilizers', (req, res) => {
  try {
    const { name, brand, type, npkRatio, description, applicationRate, frequency, season, notes } = req.body;
    
    const stmt = db.prepare(`
      INSERT INTO fertilizers (name, brand, type, npk_ratio, description, application_rate, frequency, season, notes) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    `);
    
    const result = stmt.run(name, brand, type, npkRatio, description, applicationRate, frequency, season, notes);
    
    const getStmt = db.prepare('SELECT * FROM fertilizers WHERE id = ?');
    const row = getStmt.get(result.lastInsertRowid);
    
    res.json({
      id: row.id,
      name: row.name,
      brand: row.brand,
      type: row.type,
      npkRatio: row.npk_ratio,
      description: row.description,
      applicationRate: row.application_rate,
      frequency: row.frequency,
      season: row.season,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

// Chemicals
app.get('/api/chemicals', (req, res) => {
  try {
    const stmt = db.prepare('SELECT * FROM chemicals ORDER BY name ASC');
    const rows = stmt.all();
    
    res.json(rows.map(row => ({
      id: row.id,
      name: row.name,
      brand: row.brand,
      type: row.type,
      activeIngredient: row.active_ingredient,
      concentration: row.concentration,
      targetPests: row.target_pests,
      applicationMethod: row.application_method,
      safetyPeriod: row.safety_period,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.post('/api/chemicals', (req, res) => {
  try {
    const { name, brand, type, activeIngredient, concentration, targetPests, applicationMethod, safetyPeriod, notes } = req.body;
    
    const stmt = db.prepare(`
      INSERT INTO chemicals (name, brand, type, active_ingredient, concentration, target_pests, application_method, safety_period, notes) 
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
    `);
    
    const result = stmt.run(name, brand, type, activeIngredient, concentration, targetPests, applicationMethod, safetyPeriod, notes);
    
    const getStmt = db.prepare('SELECT * FROM chemicals WHERE id = ?');
    const row = getStmt.get(result.lastInsertRowid);
    
    res.json({
      id: row.id,
      name: row.name,
      brand: row.brand,
      type: row.type,
      activeIngredient: row.active_ingredient,
      concentration: row.concentration,
      targetPests: row.target_pests,
      applicationMethod: row.application_method,
      safetyPeriod: row.safety_period,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});
// Additional endpoints for enhanced functionality

// Get plant by ID
app.get('/api/plants/:id', (req, res) => {
  try {
    const stmt = db.prepare('SELECT * FROM plants WHERE id = ?');
    const row = stmt.get(req.params.id);
    
    if (!row) {
      res.status(404).json({ error: 'Plant not found' });
      return;
    }
    
    res.json({
      id: row.id,
      type: row.type,
      variety: row.variety,
      purchaseLocation: row.purchase_location,
      seedlingAge: row.seedling_age,
      seedlingHeight: row.seedling_height,
      plantingDate: row.planting_date,
      healthStatus: row.health_status,
      currentHeight: row.current_height,
      photoUrl: row.photo_url,
      currentPhotoUrl: row.current_photo_url,
      estimatedRipeningStart: row.estimated_ripening_start,
      estimatedRipeningEnd: row.estimated_ripening_end,
      ripeningNotes: row.ripening_notes,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// Search plants
app.get('/api/plants/search', (req, res) => {
  try {
    const query = req.query.q;
    if (!query) {
      res.status(400).json({ error: 'Search query is required' });
      return;
    }
    
    const stmt = db.prepare(`
      SELECT * FROM plants WHERE variety LIKE ? OR type LIKE ? OR notes LIKE ? ORDER BY created_at DESC
    `);
    const searchTerm = `%${query}%`;
    const rows = stmt.all(searchTerm, searchTerm, searchTerm);
    
    res.json(rows.map(row => ({
      id: row.id,
      type: row.type,
      variety: row.variety,
      purchaseLocation: row.purchase_location,
      seedlingAge: row.seedling_age,
      seedlingHeight: row.seedling_height,
      plantingDate: row.planting_date,
      healthStatus: row.health_status,
      currentHeight: row.current_height,
      photoUrl: row.photo_url,
      currentPhotoUrl: row.current_photo_url,
      estimatedRipeningStart: row.estimated_ripening_start,
      estimatedRipeningEnd: row.estimated_ripening_end,
      ripeningNotes: row.ripening_notes,
      notes: row.notes,
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// Get upcoming tasks
app.get('/api/tasks/upcoming', (req, res) => {
  try {
    const days = parseInt(req.query.days) || 7;
    const endDate = new Date();
    endDate.setDate(endDate.getDate() + days);
    
    const stmt = db.prepare('SELECT * FROM tasks WHERE completed = 0 AND deadline <= ? ORDER BY deadline ASC');
    const rows = stmt.all(endDate.toISOString().split('T')[0]);
    
    res.json(rows.map(row => ({
      id: row.id,
      plantId: row.plant_id,
      title: row.title,
      description: row.description,
      deadline: row.deadline,
      completed: Boolean(row.completed),
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// Get overdue tasks
app.get('/api/tasks/overdue', (req, res) => {
  try {
    const today = new Date().toISOString().split('T')[0];
    const stmt = db.prepare('SELECT * FROM tasks WHERE completed = 0 AND deadline < ? ORDER BY deadline ASC');
    const rows = stmt.all(today);
    
    res.json(rows.map(row => ({
      id: row.id,
      plantId: row.plant_id,
      title: row.title,
      description: row.description,
      deadline: row.deadline,
      completed: Boolean(row.completed),
      createdAt: row.created_at,
      updatedAt: row.updated_at
    })));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// Dashboard summary
app.get('/api/dashboard/summary', (req, res) => {
  try {
    const results = {
      totalPlants: db.prepare('SELECT COUNT(*) as count FROM plants').get().count,
      healthyPlants: db.prepare('SELECT COUNT(*) as count FROM plants WHERE health_status = "good"').get().count,
      plantsNeedingAttention: db.prepare('SELECT COUNT(*) as count FROM plants WHERE health_status = "needs-attention"').get().count,
      totalTasks: db.prepare('SELECT COUNT(*) as count FROM tasks').get().count,
      completedTasks: db.prepare('SELECT COUNT(*) as count FROM tasks WHERE completed = 1').get().count,
      upcomingTasks: db.prepare('SELECT COUNT(*) as count FROM tasks WHERE completed = 0 AND deadline >= date("now")').get().count,
      totalHarvests: db.prepare('SELECT COUNT(*) as count FROM harvest_records').get().count,
      recentMaintenanceCount: db.prepare('SELECT COUNT(*) as count FROM maintenance_records WHERE date >= date("now", "-30 days")').get().count
    };
    
    res.json(results);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

// Error handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Something went wrong!' });
});

// Start server
app.listen(PORT, () => {
  console.log(`GardenTrack API server running on port ${PORT}`);
});

// Graceful shutdown
process.on('SIGINT', () => {
  if (db) {
    db.close();
    console.log('Database connection closed.');
  }
  process.exit(0);
});