const express = require('express');
const { Pool } = require('pg');
const cors = require('cors');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
require('dotenv').config();

const app = express();
const PORT = process.env.PORT || 80;

// PostgreSQL connection
const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: process.env.DATABASE_URL?.includes('amazonaws.com') ? { rejectUnauthorized: false } : false
});

// Middleware
app.use(cors({
  origin: true, // Allow all origins in development
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  exposedHeaders: ['Content-Length', 'Content-Type'],
  maxAge: 86400
}));
app.use(express.json());

// Handle preflight requests
app.options('*', cors());

// Health check route
app.get('/', (req, res) => {
  res.json({ status: 'ok', service: 'Filamenteka API' });
});

// JWT middleware
const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
  
  if (!token) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  
  jwt.verify(token, process.env.JWT_SECRET || 'your-secret-key', (err, user) => {
    if (err) {
      console.error('JWT verification error:', err);
      return res.status(403).json({ error: 'Invalid token' });
    }
    req.user = user;
    next();
  });
};

// Auth endpoints
app.post('/api/login', async (req, res) => {
  const { username, password } = req.body;
  
  // For now, simple hardcoded admin check
  if (username === 'admin' && password === process.env.ADMIN_PASSWORD) {
    const token = jwt.sign({ username }, process.env.JWT_SECRET || 'your-secret-key', { expiresIn: '24h' });
    res.json({ token });
  } else {
    res.status(401).json({ error: 'Invalid credentials' });
  }
});

// Colors endpoints
app.get('/api/colors', async (req, res) => {
  try {
    const result = await pool.query('SELECT * FROM colors ORDER BY name');
    res.json(result.rows);
  } catch (error) {
    console.error('Error fetching colors:', error);
    res.status(500).json({ error: 'Failed to fetch colors' });
  }
});

app.post('/api/colors', authenticateToken, async (req, res) => {
  const { name, hex, cena_refill, cena_spulna } = req.body;
  
  try {
    const result = await pool.query(
      'INSERT INTO colors (name, hex, cena_refill, cena_spulna) VALUES ($1, $2, $3, $4) RETURNING *',
      [name, hex, cena_refill || 3499, cena_spulna || 3999]
    );
    res.json(result.rows[0]);
  } catch (error) {
    console.error('Error creating color:', error);
    res.status(500).json({ error: 'Failed to create color' });
  }
});

app.put('/api/colors/:id', authenticateToken, async (req, res) => {
  const { id } = req.params;
  const { name, hex, cena_refill, cena_spulna } = req.body;
  
  try {
    const result = await pool.query(
      'UPDATE colors SET name = $1, hex = $2, cena_refill = $3, cena_spulna = $4, updated_at = CURRENT_TIMESTAMP WHERE id = $5 RETURNING *',
      [name, hex, cena_refill || 3499, cena_spulna || 3999, id]
    );
    res.json(result.rows[0]);
  } catch (error) {
    console.error('Error updating color:', error);
    res.status(500).json({ error: 'Failed to update color' });
  }
});

app.delete('/api/colors/:id', authenticateToken, async (req, res) => {
  const { id } = req.params;
  
  try {
    await pool.query('DELETE FROM colors WHERE id = $1', [id]);
    res.json({ success: true });
  } catch (error) {
    console.error('Error deleting color:', error);
    res.status(500).json({ error: 'Failed to delete color' });
  }
});

// Filaments endpoints (PUBLIC - no auth required)
app.get('/api/filaments', async (req, res) => {
  try {
    const result = await pool.query('SELECT * FROM filaments ORDER BY created_at DESC');
    res.json(result.rows);
  } catch (error) {
    console.error('Error fetching filaments:', error);
    res.status(500).json({ error: 'Failed to fetch filaments' });
  }
});

app.post('/api/filaments', authenticateToken, async (req, res) => {
  const { tip, finish, boja, boja_hex, refill, spulna, cena } = req.body;
  
  try {
    // Ensure refill and spulna are numbers
    const refillNum = parseInt(refill) || 0;
    const spulnaNum = parseInt(spulna) || 0;
    const kolicina = refillNum + spulnaNum;
    
    const result = await pool.query(
      `INSERT INTO filaments (tip, finish, boja, boja_hex, refill, spulna, kolicina, cena) 
       VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *`,
      [tip, finish, boja, boja_hex, refillNum, spulnaNum, kolicina, cena]
    );
    res.json(result.rows[0]);
  } catch (error) {
    console.error('Error creating filament:', error);
    res.status(500).json({ error: 'Failed to create filament' });
  }
});

app.put('/api/filaments/:id', authenticateToken, async (req, res) => {
  const { id } = req.params;
  const { tip, finish, boja, boja_hex, refill, spulna, cena, sale_percentage, sale_active, sale_start_date, sale_end_date } = req.body;

  try {
    // Ensure refill and spulna are numbers
    const refillNum = parseInt(refill) || 0;
    const spulnaNum = parseInt(spulna) || 0;
    const kolicina = refillNum + spulnaNum;

    // Check if sale fields are provided in the request
    const hasSaleFields = 'sale_percentage' in req.body || 'sale_active' in req.body ||
                          'sale_start_date' in req.body || 'sale_end_date' in req.body;

    let result;
    if (hasSaleFields) {
      // Update with sale fields if they are provided
      result = await pool.query(
        `UPDATE filaments
         SET tip = $1, finish = $2, boja = $3, boja_hex = $4,
             refill = $5, spulna = $6, kolicina = $7, cena = $8,
             sale_percentage = $9, sale_active = $10,
             sale_start_date = $11, sale_end_date = $12,
             updated_at = CURRENT_TIMESTAMP
         WHERE id = $13 RETURNING *`,
        [tip, finish, boja, boja_hex, refillNum, spulnaNum, kolicina, cena,
         sale_percentage || 0, sale_active || false, sale_start_date, sale_end_date, id]
      );
    } else {
      // Update without touching sale fields if they are not provided
      result = await pool.query(
        `UPDATE filaments
         SET tip = $1, finish = $2, boja = $3, boja_hex = $4,
             refill = $5, spulna = $6, kolicina = $7, cena = $8,
             updated_at = CURRENT_TIMESTAMP
         WHERE id = $9 RETURNING *`,
        [tip, finish, boja, boja_hex, refillNum, spulnaNum, kolicina, cena, id]
      );
    }

    res.json(result.rows[0]);
  } catch (error) {
    console.error('Error updating filament:', error);
    res.status(500).json({ error: 'Failed to update filament' });
  }
});

app.delete('/api/filaments/:id', authenticateToken, async (req, res) => {
  const { id } = req.params;
  
  try {
    await pool.query('DELETE FROM filaments WHERE id = $1', [id]);
    res.json({ success: true });
  } catch (error) {
    console.error('Error deleting filament:', error);
    res.status(500).json({ error: 'Failed to delete filament' });
  }
});

// Bulk sale update endpoint
app.post('/api/filaments/sale/bulk', authenticateToken, async (req, res) => {
  const { filamentIds, salePercentage, saleStartDate, saleEndDate, enableSale } = req.body;
  
  try {
    let query;
    let params;
    
    if (filamentIds && filamentIds.length > 0) {
      // Update specific filaments
      query = `
        UPDATE filaments 
        SET sale_percentage = $1, 
            sale_active = $2,
            sale_start_date = $3,
            sale_end_date = $4,
            updated_at = CURRENT_TIMESTAMP
        WHERE id = ANY($5) 
        RETURNING *`;
      params = [salePercentage || 0, enableSale || false, saleStartDate, saleEndDate, filamentIds];
    } else {
      // Update all filaments
      query = `
        UPDATE filaments 
        SET sale_percentage = $1, 
            sale_active = $2,
            sale_start_date = $3,
            sale_end_date = $4,
            updated_at = CURRENT_TIMESTAMP
        RETURNING *`;
      params = [salePercentage || 0, enableSale || false, saleStartDate, saleEndDate];
    }
    
    const result = await pool.query(query, params);
    res.json({ 
      success: true, 
      updatedCount: result.rowCount,
      updatedFilaments: result.rows 
    });
  } catch (error) {
    console.error('Error updating sale:', error);
    res.status(500).json({ error: 'Failed to update sale' });
  }
});

// Color request endpoints

// Get all color requests (admin only)
app.get('/api/color-requests', authenticateToken, async (req, res) => {
  try {
    const result = await pool.query(
      'SELECT * FROM color_requests ORDER BY created_at DESC'
    );
    res.json(result.rows);
  } catch (error) {
    console.error('Error fetching color requests:', error);
    res.status(500).json({ error: 'Failed to fetch color requests' });
  }
});

// Submit a new color request (public)
app.post('/api/color-requests', async (req, res) => {
  try {
    const { 
      color_name, 
      material_type, 
      finish_type, 
      user_email,
      user_phone, 
      user_name, 
      description,
      reference_url 
    } = req.body;

    // Validate required fields
    if (!color_name || !material_type || !user_email || !user_phone) {
      return res.status(400).json({ 
        error: 'Color name, material type, email, and phone are required' 
      });
    }

    // Check if similar request already exists
    const existingRequest = await pool.query(
      `SELECT id, request_count FROM color_requests 
       WHERE LOWER(color_name) = LOWER($1) 
       AND material_type = $2 
       AND (finish_type = $3 OR (finish_type IS NULL AND $3 IS NULL))
       AND status = 'pending'`,
      [color_name, material_type, finish_type]
    );

    if (existingRequest.rows.length > 0) {
      // Increment request count for existing request
      const result = await pool.query(
        `UPDATE color_requests 
         SET request_count = request_count + 1,
             updated_at = CURRENT_TIMESTAMP
         WHERE id = $1
         RETURNING *`,
        [existingRequest.rows[0].id]
      );
      res.json({ 
        message: 'Your request has been added to an existing request for this color',
        request: result.rows[0] 
      });
    } else {
      // Create new request
      const result = await pool.query(
        `INSERT INTO color_requests 
         (color_name, material_type, finish_type, user_email, user_phone, user_name, description, reference_url)
         VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
         RETURNING *`,
        [color_name, material_type, finish_type, user_email, user_phone, user_name, description, reference_url]
      );
      res.json({ 
        message: 'Color request submitted successfully',
        request: result.rows[0] 
      });
    }
  } catch (error) {
    console.error('Error creating color request:', error);
    res.status(500).json({ error: 'Failed to submit color request' });
  }
});

// Update color request status (admin only)
app.put('/api/color-requests/:id', authenticateToken, async (req, res) => {
  try {
    const { id } = req.params;
    const { status, admin_notes } = req.body;
    
    const result = await pool.query(
      `UPDATE color_requests 
       SET status = $1, 
           admin_notes = $2,
           processed_at = CURRENT_TIMESTAMP,
           processed_by = $3,
           updated_at = CURRENT_TIMESTAMP
       WHERE id = $4
       RETURNING *`,
      [status, admin_notes, req.user.username, id]
    );
    
    if (result.rows.length === 0) {
      return res.status(404).json({ error: 'Color request not found' });
    }
    
    res.json(result.rows[0]);
  } catch (error) {
    console.error('Error updating color request:', error);
    res.status(500).json({ error: 'Failed to update color request' });
  }
});

// Delete color request (admin only)
app.delete('/api/color-requests/:id', authenticateToken, async (req, res) => {
  try {
    const { id } = req.params;
    
    const result = await pool.query(
      'DELETE FROM color_requests WHERE id = $1 RETURNING *',
      [id]
    );
    
    if (result.rows.length === 0) {
      return res.status(404).json({ error: 'Color request not found' });
    }
    
    res.json({ message: 'Color request deleted successfully' });
  } catch (error) {
    console.error('Error deleting color request:', error);
    res.status(500).json({ error: 'Failed to delete color request' });
  }
});

// ==========================================
// Customer endpoints (admin-only)
// ==========================================

app.get('/api/customers', authenticateToken, async (req, res) => {
  try {
    const result = await pool.query('SELECT * FROM customers ORDER BY name');
    res.json(result.rows);
  } catch (error) {
    console.error('Error fetching customers:', error);
    res.status(500).json({ error: 'Failed to fetch customers' });
  }
});

app.get('/api/customers/search', authenticateToken, async (req, res) => {
  try {
    const { q } = req.query;
    if (!q) return res.json([]);
    const result = await pool.query(
      `SELECT * FROM customers WHERE name ILIKE $1 OR phone ILIKE $1 ORDER BY name LIMIT 10`,
      [`%${q}%`]
    );
    res.json(result.rows);
  } catch (error) {
    console.error('Error searching customers:', error);
    res.status(500).json({ error: 'Failed to search customers' });
  }
});

app.get('/api/customers/:id', authenticateToken, async (req, res) => {
  try {
    const { id } = req.params;
    const customerResult = await pool.query('SELECT * FROM customers WHERE id = $1', [id]);
    if (customerResult.rows.length === 0) {
      return res.status(404).json({ error: 'Customer not found' });
    }
    const salesResult = await pool.query(
      `SELECT s.*,
        (SELECT COUNT(*) FROM sale_items si WHERE si.sale_id = s.id) as item_count
       FROM sales s WHERE s.customer_id = $1 ORDER BY s.created_at DESC`,
      [id]
    );
    res.json({ ...customerResult.rows[0], sales: salesResult.rows });
  } catch (error) {
    console.error('Error fetching customer:', error);
    res.status(500).json({ error: 'Failed to fetch customer' });
  }
});

app.post('/api/customers', authenticateToken, async (req, res) => {
  const { name, phone, city, notes } = req.body;
  if (!name) return res.status(400).json({ error: 'Name is required' });
  try {
    const result = await pool.query(
      'INSERT INTO customers (name, phone, city, notes) VALUES ($1, $2, $3, $4) RETURNING *',
      [name, phone || null, city || null, notes || null]
    );
    res.json(result.rows[0]);
  } catch (error) {
    if (error.code === '23505') {
      return res.status(409).json({ error: 'Customer with this phone already exists' });
    }
    console.error('Error creating customer:', error);
    res.status(500).json({ error: 'Failed to create customer' });
  }
});

app.put('/api/customers/:id', authenticateToken, async (req, res) => {
  const { id } = req.params;
  const { name, phone, city, notes } = req.body;
  try {
    const result = await pool.query(
      `UPDATE customers SET name = $1, phone = $2, city = $3, notes = $4, updated_at = CURRENT_TIMESTAMP
       WHERE id = $5 RETURNING *`,
      [name, phone || null, city || null, notes || null, id]
    );
    if (result.rows.length === 0) return res.status(404).json({ error: 'Customer not found' });
    res.json(result.rows[0]);
  } catch (error) {
    console.error('Error updating customer:', error);
    res.status(500).json({ error: 'Failed to update customer' });
  }
});

// ==========================================
// Sale endpoints (admin-only)
// ==========================================

app.post('/api/sales', authenticateToken, async (req, res) => {
  const client = await pool.connect();
  try {
    await client.query('BEGIN');
    const { customer, items, notes } = req.body;

    if (!customer || !customer.name) {
      await client.query('ROLLBACK');
      return res.status(400).json({ error: 'Customer name is required' });
    }
    if (!items || items.length === 0) {
      await client.query('ROLLBACK');
      return res.status(400).json({ error: 'At least one item is required' });
    }

    // Find-or-create customer by phone
    let customerId;
    if (customer.phone) {
      const existing = await client.query(
        'SELECT id FROM customers WHERE phone = $1', [customer.phone]
      );
      if (existing.rows.length > 0) {
        customerId = existing.rows[0].id;
        // Update name/city if provided
        await client.query(
          `UPDATE customers SET name = $1, city = COALESCE($2, city), notes = COALESCE($3, notes), updated_at = CURRENT_TIMESTAMP WHERE id = $4`,
          [customer.name, customer.city, customer.notes, customerId]
        );
      }
    }
    if (!customerId) {
      const newCust = await client.query(
        'INSERT INTO customers (name, phone, city, notes) VALUES ($1, $2, $3, $4) RETURNING id',
        [customer.name, customer.phone || null, customer.city || null, customer.notes || null]
      );
      customerId = newCust.rows[0].id;
    }

    // Process items
    let totalAmount = 0;
    const saleItems = [];

    for (const item of items) {
      const { filament_id, item_type, quantity } = item;
      if (!['refill', 'spulna'].includes(item_type)) {
        await client.query('ROLLBACK');
        return res.status(400).json({ error: `Invalid item_type: ${item_type}` });
      }

      // Get filament with stock check
      const filamentResult = await client.query(
        'SELECT f.*, c.cena_refill, c.cena_spulna FROM filaments f JOIN colors c ON f.boja = c.name WHERE f.id = $1 FOR UPDATE',
        [filament_id]
      );
      if (filamentResult.rows.length === 0) {
        await client.query('ROLLBACK');
        return res.status(400).json({ error: `Filament ${filament_id} not found` });
      }

      const filament = filamentResult.rows[0];
      if (filament[item_type] < quantity) {
        await client.query('ROLLBACK');
        return res.status(400).json({
          error: `Insufficient stock for ${filament.boja} ${item_type}: have ${filament[item_type]}, need ${quantity}`
        });
      }

      // Determine price (apply sale discount if active)
      let unitPrice = item_type === 'refill' ? (filament.cena_refill || 3499) : (filament.cena_spulna || 3999);
      if (filament.sale_active && filament.sale_percentage > 0) {
        unitPrice = Math.round(unitPrice * (1 - filament.sale_percentage / 100));
      }

      // Decrement inventory
      const updateField = item_type === 'refill' ? 'refill' : 'spulna';
      await client.query(
        `UPDATE filaments SET ${updateField} = ${updateField} - $1, kolicina = kolicina - $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2`,
        [quantity, filament_id]
      );

      totalAmount += unitPrice * quantity;
      saleItems.push({ filament_id, item_type, quantity, unit_price: unitPrice });
    }

    // Insert sale
    const saleResult = await client.query(
      'INSERT INTO sales (customer_id, total_amount, notes) VALUES ($1, $2, $3) RETURNING *',
      [customerId, totalAmount, notes || null]
    );
    const sale = saleResult.rows[0];

    // Insert sale items
    for (const si of saleItems) {
      await client.query(
        'INSERT INTO sale_items (sale_id, filament_id, item_type, quantity, unit_price) VALUES ($1, $2, $3, $4, $5)',
        [sale.id, si.filament_id, si.item_type, si.quantity, si.unit_price]
      );
    }

    await client.query('COMMIT');

    // Fetch full sale with items
    const fullSale = await pool.query(
      `SELECT s.*, c.name as customer_name, c.phone as customer_phone
       FROM sales s LEFT JOIN customers c ON s.customer_id = c.id WHERE s.id = $1`,
      [sale.id]
    );
    const fullItems = await pool.query(
      `SELECT si.*, f.tip as filament_tip, f.finish as filament_finish, f.boja as filament_boja
       FROM sale_items si JOIN filaments f ON si.filament_id = f.id WHERE si.sale_id = $1`,
      [sale.id]
    );
    res.json({ ...fullSale.rows[0], items: fullItems.rows });
  } catch (error) {
    await client.query('ROLLBACK');
    console.error('Error creating sale:', error);
    res.status(500).json({ error: 'Failed to create sale' });
  } finally {
    client.release();
  }
});

app.get('/api/sales', authenticateToken, async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 50;
    const offset = (page - 1) * limit;

    const countResult = await pool.query('SELECT COUNT(*) FROM sales');
    const total = parseInt(countResult.rows[0].count);

    const result = await pool.query(
      `SELECT s.*, c.name as customer_name, c.phone as customer_phone,
        (SELECT COUNT(*) FROM sale_items si WHERE si.sale_id = s.id) as item_count
       FROM sales s LEFT JOIN customers c ON s.customer_id = c.id
       ORDER BY s.created_at DESC LIMIT $1 OFFSET $2`,
      [limit, offset]
    );
    res.json({ sales: result.rows, total });
  } catch (error) {
    console.error('Error fetching sales:', error);
    res.status(500).json({ error: 'Failed to fetch sales' });
  }
});

app.get('/api/sales/:id', authenticateToken, async (req, res) => {
  try {
    const { id } = req.params;
    const saleResult = await pool.query(
      `SELECT s.*, c.name as customer_name, c.phone as customer_phone, c.city as customer_city
       FROM sales s LEFT JOIN customers c ON s.customer_id = c.id WHERE s.id = $1`,
      [id]
    );
    if (saleResult.rows.length === 0) return res.status(404).json({ error: 'Sale not found' });

    const itemsResult = await pool.query(
      `SELECT si.*, f.tip as filament_tip, f.finish as filament_finish, f.boja as filament_boja
       FROM sale_items si JOIN filaments f ON si.filament_id = f.id WHERE si.sale_id = $1 ORDER BY si.created_at`,
      [id]
    );
    res.json({ ...saleResult.rows[0], items: itemsResult.rows });
  } catch (error) {
    console.error('Error fetching sale:', error);
    res.status(500).json({ error: 'Failed to fetch sale' });
  }
});

app.delete('/api/sales/:id', authenticateToken, async (req, res) => {
  const client = await pool.connect();
  try {
    await client.query('BEGIN');
    const { id } = req.params;

    // Get sale items to restore inventory
    const itemsResult = await client.query('SELECT * FROM sale_items WHERE sale_id = $1', [id]);
    if (itemsResult.rows.length === 0) {
      await client.query('ROLLBACK');
      return res.status(404).json({ error: 'Sale not found' });
    }

    // Restore inventory for each item
    for (const item of itemsResult.rows) {
      const updateField = item.item_type === 'refill' ? 'refill' : 'spulna';
      await client.query(
        `UPDATE filaments SET ${updateField} = ${updateField} + $1, kolicina = kolicina + $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2`,
        [item.quantity, item.filament_id]
      );
    }

    // Delete sale (cascade deletes sale_items)
    await client.query('DELETE FROM sales WHERE id = $1', [id]);
    await client.query('COMMIT');
    res.json({ success: true });
  } catch (error) {
    await client.query('ROLLBACK');
    console.error('Error deleting sale:', error);
    res.status(500).json({ error: 'Failed to delete sale' });
  } finally {
    client.release();
  }
});

// ==========================================
// Analytics endpoints (admin-only)
// ==========================================

function getPeriodInterval(period) {
  const map = {
    '7d': '7 days', '30d': '30 days', '90d': '90 days',
    '6m': '6 months', '1y': '1 year', 'all': '100 years'
  };
  return map[period] || '30 days';
}

app.get('/api/analytics/overview', authenticateToken, async (req, res) => {
  try {
    const interval = getPeriodInterval(req.query.period);
    const result = await pool.query(
      `SELECT
        COALESCE(SUM(total_amount), 0) as revenue,
        COUNT(*) as sales_count,
        COALESCE(ROUND(AVG(total_amount)), 0) as avg_order_value,
        COUNT(DISTINCT customer_id) as unique_customers
       FROM sales WHERE created_at >= NOW() - $1::interval`,
      [interval]
    );
    res.json(result.rows[0]);
  } catch (error) {
    console.error('Error fetching analytics overview:', error);
    res.status(500).json({ error: 'Failed to fetch analytics' });
  }
});

app.get('/api/analytics/top-sellers', authenticateToken, async (req, res) => {
  try {
    const interval = getPeriodInterval(req.query.period);
    const result = await pool.query(
      `SELECT f.boja, f.tip, f.finish,
        SUM(si.quantity) as total_qty,
        SUM(si.quantity * si.unit_price) as total_revenue
       FROM sale_items si
       JOIN filaments f ON si.filament_id = f.id
       JOIN sales s ON si.sale_id = s.id
       WHERE s.created_at >= NOW() - $1::interval
       GROUP BY f.boja, f.tip, f.finish
       ORDER BY total_qty DESC LIMIT 10`,
      [interval]
    );
    res.json(result.rows);
  } catch (error) {
    console.error('Error fetching top sellers:', error);
    res.status(500).json({ error: 'Failed to fetch top sellers' });
  }
});

app.get('/api/analytics/inventory-alerts', authenticateToken, async (req, res) => {
  try {
    const result = await pool.query(
      `SELECT f.id, f.boja, f.tip, f.finish, f.refill, f.spulna, f.kolicina,
        COALESCE(
          (SELECT SUM(si.quantity)::float / GREATEST(EXTRACT(EPOCH FROM (NOW() - MIN(s.created_at))) / 86400, 1)
           FROM sale_items si JOIN sales s ON si.sale_id = s.id
           WHERE si.filament_id = f.id AND s.created_at >= NOW() - INTERVAL '90 days'),
          0
        ) as avg_daily_sales
       FROM filaments f
       WHERE f.kolicina <= 5
       ORDER BY f.kolicina ASC, f.boja`
    );
    const rows = result.rows.map(r => ({
      ...r,
      avg_daily_sales: parseFloat(r.avg_daily_sales) || 0,
      days_until_stockout: r.avg_daily_sales > 0
        ? Math.round(r.kolicina / r.avg_daily_sales)
        : null
    }));
    res.json(rows);
  } catch (error) {
    console.error('Error fetching inventory alerts:', error);
    res.status(500).json({ error: 'Failed to fetch inventory alerts' });
  }
});

app.get('/api/analytics/revenue-chart', authenticateToken, async (req, res) => {
  try {
    const interval = getPeriodInterval(req.query.period || '6m');
    const group = req.query.group || 'month';
    const truncTo = group === 'day' ? 'day' : group === 'week' ? 'week' : 'month';

    const result = await pool.query(
      `SELECT DATE_TRUNC($1, created_at) as period,
        SUM(total_amount) as revenue,
        COUNT(*) as count
       FROM sales
       WHERE created_at >= NOW() - $2::interval
       GROUP BY DATE_TRUNC($1, created_at)
       ORDER BY period`,
      [truncTo, interval]
    );
    res.json(result.rows);
  } catch (error) {
    console.error('Error fetching revenue chart:', error);
    res.status(500).json({ error: 'Failed to fetch revenue chart' });
  }
});

app.get('/api/analytics/type-breakdown', authenticateToken, async (req, res) => {
  try {
    const interval = getPeriodInterval(req.query.period);
    const result = await pool.query(
      `SELECT si.item_type,
        SUM(si.quantity) as total_qty,
        SUM(si.quantity * si.unit_price) as total_revenue
       FROM sale_items si
       JOIN sales s ON si.sale_id = s.id
       WHERE s.created_at >= NOW() - $1::interval
       GROUP BY si.item_type`,
      [interval]
    );
    res.json(result.rows);
  } catch (error) {
    console.error('Error fetching type breakdown:', error);
    res.status(500).json({ error: 'Failed to fetch type breakdown' });
  }
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});