<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Models\ReportModel;
use Core\Request;

final class ReportController extends BaseController
{
    private ReportModel $model;

    public function __construct()
    {
        parent::__construct();
        $this->model = new ReportModel();
    }

    // ── Item-wise sales ───────────────────────────────────────────────────────

    public function sales(): void
    {
        $this->requirePermission('report.view');

        [$from, $to] = $this->dateRange();
        $search      = Request::str('search');

        $rows    = $this->model->itemSales($from, $to, $search);
        $summary = $this->model->summary($from, $to);
        $daily   = $this->model->dailySales($from, $to);

        if (Request::str('export') === 'csv') {
            $this->exportCsv(
                'item_sales_' . $from . '_' . $to,
                ['Item Name', 'Orders', 'Qty Sold', 'Revenue'],
                array_map(fn($r) => [
                    $r['item_name'],
                    $r['order_count'],
                    $r['total_qty'],
                    number_format((float)$r['total_revenue'], 2),
                ], $rows)
            );
        }

        $this->view('reports/sales', [
            'title'   => 'Item-wise Sales Report',
            'rows'    => $rows,
            'summary' => $summary,
            'daily'   => $daily,
            'from'    => $from,
            'to'      => $to,
            'search'  => $search,
        ]);
    }

    // ── Invoice / order-wise ──────────────────────────────────────────────────

    public function invoices(): void
    {
        $this->requirePermission('report.view');

        [$from, $to] = $this->dateRange();
        $status      = Request::str('status');
        $search      = Request::str('search');

        $rows    = $this->model->invoiceReport($from, $to, $status, $search);
        $summary = $this->model->summary($from, $to);

        if (Request::str('export') === 'csv') {
            $this->exportCsv(
                'orders_' . $from . '_' . $to,
                ['Order #', 'Invoice #', 'Customer', 'Phone', 'Status', 'Payment', 'Total', 'Date'],
                array_map(fn($r) => [
                    $r['order_number'],
                    $r['invoice_number'] ?? '',
                    $r['customer_name'],
                    $r['customer_phone'] ?? '',
                    ucfirst($r['status']),
                    ucfirst($r['payment_method']),
                    number_format((float)$r['total_amount'], 2),
                    date('d M Y H:i', strtotime($r['placed_at'])),
                ], $rows)
            );
        }

        $statuses = ['pending','confirmed','cooking','ready','picked_up','on_the_way','delivered','cancelled'];

        $this->view('reports/invoices', [
            'title'    => 'Order-wise Report',
            'rows'     => $rows,
            'summary'  => $summary,
            'from'     => $from,
            'to'       => $to,
            'status'   => $status,
            'search'   => $search,
            'statuses' => $statuses,
        ]);
    }

    // ── Customer history ──────────────────────────────────────────────────────

    public function customers(): void
    {
        $this->requirePermission('report.view');

        [$from, $to] = $this->dateRange();
        $search      = Request::str('search');

        $rows    = $this->model->customerSummary($from, $to, $search);
        $summary = $this->model->summary($from, $to);

        if (Request::str('export') === 'csv') {
            $this->exportCsv(
                'customers_' . $from . '_' . $to,
                ['Name', 'Phone', 'Email', 'Total Orders', 'Total Spent', 'Cancelled', 'Last Order'],
                array_map(fn($r) => [
                    $r['name'],
                    $r['phone'] ?? '',
                    $r['email'] ?? '',
                    $r['total_orders'],
                    number_format((float)$r['total_spent'], 2),
                    $r['cancelled_orders'],
                    $r['last_order_at'] ? date('d M Y', strtotime($r['last_order_at'])) : '',
                ], $rows)
            );
        }

        $this->view('reports/customers', [
            'title'   => 'Customer History',
            'rows'    => $rows,
            'summary' => $summary,
            'from'    => $from,
            'to'      => $to,
            'search'  => $search,
        ]);
    }

    // ── Customer order drill-down ─────────────────────────────────────────────

    public function customerDetail(array $params = []): void
    {
        $this->requirePermission('report.view');

        $userId = (int)($params['id'] ?? 0);
        $orders = $this->model->customerOrders($userId);

        $customer = \Core\Database::getInstance()->fetchOne(
            "SELECT u.name, u.email, u.phone FROM users u WHERE u.id = ?", [$userId]
        );

        $this->view('reports/customer_detail', [
            'title'    => 'Orders — ' . ($customer['name'] ?? 'Customer'),
            'customer' => $customer,
            'orders'   => $orders,
        ]);
    }

    // ── Cash summary ─────────────────────────────────────────────────────────

    public function cashSummary(): void
    {
        $this->requirePermission('report.cash');

        [$from, $to] = $this->dateRange();

        // Total collected per payment mode (from split payments table)
        $byMode = $this->db->fetchAll(
            "SELECT op.mode,
                    COUNT(DISTINCT op.order_id) AS orders,
                    SUM(op.amount)              AS total
               FROM order_payments op
               JOIN orders o ON o.id = op.order_id
              WHERE o.payment_status = 'paid'
                AND DATE(o.placed_at) BETWEEN ? AND ?
              GROUP BY op.mode
              ORDER BY total DESC",
            [$from, $to]
        );

        // Also include paid orders that have no split rows (legacy / direct cash)
        $legacy = $this->db->fetchAll(
            "SELECT COALESCE(o.collected_via, o.payment_method, 'Cash') AS mode,
                    COUNT(*)          AS orders,
                    SUM(o.total_amount) AS total
               FROM orders o
              WHERE o.payment_status = 'paid'
                AND DATE(o.placed_at) BETWEEN ? AND ?
                AND NOT EXISTS (SELECT 1 FROM order_payments op WHERE op.order_id = o.id)
              GROUP BY mode",
            [$from, $to]
        );
        // Merge legacy into byMode
        foreach ($legacy as $leg) {
            $found = false;
            foreach ($byMode as &$bm) {
                if ($bm['mode'] === $leg['mode']) {
                    $bm['orders'] += $leg['orders'];
                    $bm['total']  += $leg['total'];
                    $found = true; break;
                }
            }
            unset($bm);
            if (!$found) $byMode[] = $leg;
        }
        usort($byMode, fn($a, $b) => $b['total'] <=> $a['total']);

        // Daily breakdown per mode (for chart)
        $daily = $this->db->fetchAll(
            "SELECT DATE(o.placed_at) AS day,
                    op.mode,
                    SUM(op.amount) AS total
               FROM order_payments op
               JOIN orders o ON o.id = op.order_id
              WHERE o.payment_status = 'paid'
                AND DATE(o.placed_at) BETWEEN ? AND ?
              GROUP BY day, op.mode
              ORDER BY day ASC",
            [$from, $to]
        );

        // Unpaid totals
        $unpaid = $this->db->fetchOne(
            "SELECT COUNT(*) AS orders, COALESCE(SUM(total_amount),0) AS total
               FROM orders
              WHERE (payment_status IS NULL OR payment_status != 'paid')
                AND status NOT IN ('cancelled')
                AND DATE(placed_at) BETWEEN ? AND ?",
            [$from, $to]
        );

        $this->view('reports/cash_summary', [
            'title'  => 'Cash Summary',
            'byMode' => $byMode,
            'daily'  => $daily,
            'unpaid' => $unpaid,
            'from'   => $from,
            'to'     => $to,
        ]);
    }

    // ── Helpers ───────────────────────────────────────────────────────────────

    private function dateRange(): array
    {
        $from = Request::str('from') ?: date('Y-m-01');
        $to   = Request::str('to')   ?: date('Y-m-d');
        return [$from, $to];
    }

    private function exportCsv(string $filename, array $headers, array $rows): never
    {
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="' . $filename . '.csv"');
        header('Cache-Control: no-cache');

        $fp = fopen('php://output', 'w');
        fputcsv($fp, $headers);
        foreach ($rows as $row) {
            fputcsv($fp, $row);
        }
        fclose($fp);
        exit;
    }
}
