<?php
class CustomerController extends Controller
{
    public function index(): void
    {
        Auth::requirePermission('customers.view');

        $search  = trim($this->get('search', ''));
        $status  = $this->get('status', 'active');
        $balance = $this->get('balance', 'all'); // all | due | clear

        $where  = ['1=1'];
        $params = [];

        if ($search) {
            $where[]  = '(c.customer_name LIKE ? OR c.phone LIKE ? OR c.email LIKE ?)';
            $params[] = "%$search%";
            $params[] = "%$search%";
            $params[] = "%$search%";
        }
        if ($status !== 'all') {
            $where[]  = 'c.status = ?';
            $params[] = $status;
        }
        if ($balance === 'due') {
            $where[] = 'c.current_balance > 0';
        } elseif ($balance === 'clear') {
            $where[] = 'c.current_balance <= 0';
        }

        $sql = "SELECT c.*,
                       COUNT(s.id)              AS total_invoices,
                       COALESCE(SUM(s.total),0) AS total_spent,
                       MAX(s.sale_date)         AS last_purchase
                FROM customers c
                LEFT JOIN sales s ON s.customer_id = c.id AND s.status = 'completed'
                WHERE " . implode(' AND ', $where) . "
                GROUP BY c.id
                ORDER BY c.customer_name ASC";

        $pagination = Database::paginate($sql, $params, max(1, (int)$this->get('page', 1)));

        // Summary stats
        $totalCustomers  = (int)   Database::fetchColumn("SELECT COUNT(*) FROM customers WHERE status='active'");
        $totalBalance    = (float) Database::fetchColumn("SELECT COALESCE(SUM(current_balance),0) FROM customers WHERE status='active'");
        $customersWithDue= (int)   Database::fetchColumn("SELECT COUNT(*) FROM customers WHERE status='active' AND current_balance > 0");

        $pageTitle  = 'Customers';
        $breadcrumb = [['label' => 'Customers']];
        ob_start();
        require APP_PATH . '/views/customers/index.php';
        $content = ob_get_clean();
        require APP_PATH . '/views/layouts/main.php';
    }
    public function create(): void
    {
        Auth::requirePermission('customers.create');
        $pageTitle='Add Customer';
        ob_start(); require APP_PATH.'/views/customers/form.php'; $content=ob_get_clean();
        require APP_PATH.'/views/layouts/main.php';
    }
    public function store(): void
    {
        Auth::requirePermission('customers.create'); Auth::requireCsrf();
        $d = $this->customerData();
        Database::insert('INSERT INTO customers (customer_name,phone,email,address,credit_limit,opening_balance,current_balance,status) VALUES (?,?,?,?,?,?,?,?)',
            [$d['name'],$d['phone'],$d['email'],$d['address'],$d['credit'],$d['opening'],$d['opening'],'active']);
        redirectWith(APP_URL.'/customers','success','Customer added.');
    }
    public function edit(string $id): void
    {
        Auth::requirePermission('customers.edit');
        $customer = Database::fetchOne('SELECT * FROM customers WHERE id=?',[(int)$id]);
        if (!$customer) { http_response_code(404); die('Not found.'); }
        $pageTitle='Edit Customer';
        ob_start(); require APP_PATH.'/views/customers/form.php'; $content=ob_get_clean();
        require APP_PATH.'/views/layouts/main.php';
    }
    public function update(string $id): void
    {
        Auth::requirePermission('customers.edit'); Auth::requireCsrf();
        $d = $this->customerData();
        Database::execute('UPDATE customers SET customer_name=?,phone=?,email=?,address=?,credit_limit=?,status=? WHERE id=?',
            [$d['name'],$d['phone'],$d['email'],$d['address'],$d['credit'],$d['status'],(int)$id]);
        redirectWith(APP_URL.'/customers','success','Customer updated.');
    }
    public function show(string $id): void
    {
        Auth::requirePermission('customers.view');

        $customer = Database::fetchOne(
            'SELECT * FROM customers WHERE id = ?', [(int)$id]
        );
        if (!$customer) {
            redirectWith(APP_URL . '/customers', 'error', 'Customer not found.');
            return;
        }

        // Sales summary
        $summary = Database::fetchOne(
            "SELECT COUNT(*)                          AS total_invoices,
                    COALESCE(SUM(total),0)            AS total_revenue,
                    COALESCE(SUM(paid),0)             AS total_paid,
                    COALESCE(SUM(balance),0)          AS total_balance,
                    COALESCE(SUM(discount),0)         AS total_discount,
                    COUNT(CASE WHEN payment_status='paid' THEN 1 END)    AS paid_count,
                    COUNT(CASE WHEN payment_status='partial' THEN 1 END) AS partial_count,
                    COUNT(CASE WHEN payment_status='due' THEN 1 END)     AS due_count,
                    COUNT(CASE WHEN status='returned' THEN 1 END)        AS return_count,
                    MIN(sale_date) AS first_sale,
                    MAX(sale_date) AS last_sale
             FROM sales
             WHERE customer_id = ? AND status IN ('completed','returned')",
            [(int)$id]
        );

        // Recent sales (last 25)
        $sales = Database::fetchAll(
            "SELECT s.*, u.name AS cashier_name
             FROM sales s
             LEFT JOIN users u ON u.id = s.created_by
             WHERE s.customer_id = ?
             ORDER BY s.sale_date DESC LIMIT 25",
            [(int)$id]
        );

        // Credit / payment history
        $payments = Database::fetchAll(
            "SELECT cp.*, s.invoice_no
             FROM customer_payments cp
             LEFT JOIN sales s ON s.id = cp.sale_id
             WHERE cp.customer_id = ?
             ORDER BY cp.payment_date DESC LIMIT 20",
            [(int)$id]
        );

        // Outstanding credit sales
        $creditSales = Database::fetchAll(
            "SELECT s.id, s.invoice_no, s.sale_date, s.total, s.paid, s.balance
             FROM sales s
             WHERE s.customer_id = ? AND s.status = 'completed'
               AND s.balance > 0
               AND EXISTS (
                   SELECT 1 FROM sale_payments sp
                   WHERE sp.sale_id = s.id AND sp.payment_method = 'credit'
               )
             ORDER BY s.sale_date ASC",
            [(int)$id]
        );

        // Top 5 products purchased
        $topProducts = Database::fetchAll(
            "SELECT p.product_name, p.product_code,
                    COUNT(DISTINCT s.id)       AS invoice_count,
                    SUM(si.quantity)           AS total_qty,
                    SUM(si.total)              AS total_spent
             FROM sale_items si
             JOIN sales s ON s.id = si.sale_id
             JOIN products p ON p.id = si.product_id
             WHERE s.customer_id = ? AND s.status = 'completed'
             GROUP BY p.id
             ORDER BY total_spent DESC LIMIT 5",
            [(int)$id]
        );

        $pageTitle  = $customer['customer_name'];
        $breadcrumb = [
            ['label' => 'Customers', 'url' => APP_URL . '/customers'],
            ['label' => $customer['customer_name']],
        ];
        ob_start();
        require APP_PATH . '/views/customers/view.php';
        $content = ob_get_clean();
        require APP_PATH . '/views/layouts/main.php';
    }
    // ── Delete a customer ─────────────────────────────────────
    public function delete(string $id): void
    {
        Auth::requirePermission('customers.delete');
        Auth::requireCsrf();

        $custId = (int) $id;

        // Protect the default Walk-in Customer (id=1)
        if ($custId === 1) {
            redirectWith(APP_URL.'/customers', 'error',
                'Walk-in Customer cannot be deleted.');
            return;
        }

        $cust = Database::fetchOne('SELECT * FROM customers WHERE id = ?', [$custId]);
        if (!$cust) {
            redirectWith(APP_URL.'/customers', 'error', 'Customer not found.');
            return;
        }

        // Check for any related history that would block a hard delete
        $saleCount = (int) Database::fetchColumn(
            'SELECT COUNT(*) FROM sales WHERE customer_id = ?', [$custId]
        );
        $paymentCount = (int) Database::fetchColumn(
            'SELECT COUNT(*) FROM customer_payments WHERE customer_id = ?', [$custId]
        );
        $heldCount = 0;
        try {
            $heldCount = (int) Database::fetchColumn(
                'SELECT COUNT(*) FROM held_bills WHERE customer_id = ?', [$custId]
            );
        } catch (\Exception $e) {}

        if ($saleCount > 0 || $paymentCount > 0 || $heldCount > 0) {
            // Has history — cannot hard delete safely. Deactivate instead.
            Database::execute(
                "UPDATE customers SET status = 'inactive' WHERE id = ?", [$custId]
            );
            Auth::logAudit(Auth::id(), 'customer_deactivate', 'customers',
                "Customer \"{$cust['customer_name']}\" deactivated (has {$saleCount} sales, ".
                "{$paymentCount} payments) — could not hard delete.");
            redirectWith(APP_URL.'/customers', 'success',
                "\"{$cust['customer_name']}\" has {$saleCount} invoice(s) on record, so it was ".
                'deactivated instead of deleted (history is preserved).');
            return;
        }

        // No history — safe to permanently delete
        try {
            Database::execute('DELETE FROM customers WHERE id = ?', [$custId]);
            Auth::logAudit(Auth::id(), 'customer_delete', 'customers',
                "Customer \"{$cust['customer_name']}\" permanently deleted.");
            redirectWith(APP_URL.'/customers', 'success',
                "\"{$cust['customer_name']}\" deleted permanently.");
        } catch (\Exception $e) {
            redirectWith(APP_URL.'/customers', 'error',
                'Delete failed: ' . $e->getMessage());
        }
    }

    public function search(): void
    {
        Auth::requireLogin();
        $q = trim($this->get('q',''));
        if (!$q) { $this->json([]); return; }
        $this->json(Database::fetchAll(
            "SELECT id, customer_name, phone, current_balance, credit_limit
             FROM customers
             WHERE status = 'active'
               AND (customer_name LIKE ? OR phone LIKE ?)
             LIMIT 10",
            ["%$q%", "%$q%"]
        ));
    }
    private function customerData(): array
    {
        return ['name'=>trim($this->post('customer_name','')),'phone'=>trim($this->post('phone','')),
            'email'=>trim($this->post('email','')),'address'=>trim($this->post('address','')),
            'credit'=>(float)$this->post('credit_limit',0),'opening'=>(float)$this->post('opening_balance',0),
            'status'=>$this->post('status','active')];
    }
}