<?php

namespace Modules\Reports\Controllers;

use core\Controller;
use core\Auth;
use core\Database;
use core\View;
use Modules\Reports\Models\Report;

class ReportController extends Controller
{
    private Report $reportModel;

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

    public function index(): void
    {
        Auth::requirePermission('reports_view');

        $this->view('Reports/index', [
            'title' => 'Reports',
            'breadcrumb' => ['Reports' => url('reports')],
        ]);
    }

    public function dailySales(): void
    {
        Auth::requirePermission('reports_view');
        $date = $this->request->get('date', date('Y-m-d'));
        $data = $this->reportModel->getDailySales($date);
        $summary = $this->reportModel->getDailySalesSummary($date);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data, 'summary' => $summary]);
            return;
        }

        $this->view('Reports/daily_sales', [
            'title' => 'Daily Sales Report',
            'date' => $date,
            'sales' => $data,
            'summary' => $summary,
            'breadcrumb' => ['Reports' => url('reports'), 'Daily Sales' => url('reports/daily-sales')],
        ]);
    }

    public function monthlySales(): void
    {
        Auth::requirePermission('reports_view');
        $month = $this->request->get('month', date('m'));
        $year = $this->request->get('year', date('Y'));
        $data = $this->reportModel->getMonthlySales($month, $year);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $this->view('Reports/monthly_sales', [
            'title' => 'Monthly Sales Report',
            'month' => $month,
            'year' => $year,
            'sales' => $data,
            'breadcrumb' => ['Reports' => url('reports'), 'Monthly Sales' => url('reports/monthly-sales')],
        ]);
    }

    public function yearlySales(): void
    {
        Auth::requirePermission('reports_view');
        $year = $this->request->get('year', date('Y'));
        $data = $this->reportModel->getYearlySales($year);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $this->view('Reports/yearly_sales', [
            'title' => 'Yearly Sales Report',
            'year' => $year,
            'sales' => $data,
            'breadcrumb' => ['Reports' => url('reports'), 'Yearly Sales' => url('reports/yearly-sales')],
        ]);
    }

    public function profitLoss(): void
    {
        Auth::requirePermission('reports_view');
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));
        $data = $this->reportModel->getProfitLoss($startDate, $endDate);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $this->view('Reports/profit_loss', [
            'title' => 'Profit & Loss Report',
            'startDate' => $startDate,
            'endDate' => $endDate,
            'report' => $data,
            'breadcrumb' => ['Reports' => url('reports'), 'Profit & Loss' => url('reports/profit-loss')],
        ]);
    }

    public function inventory(): void
    {
        Auth::requirePermission('reports_view');
        $categoryId = $this->request->get('category_id');
        $data = $this->reportModel->getInventoryReport($categoryId);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $db = Database::getInstance();
        $categories = $db->table('categories')->where('type', 'product')->get();

        $this->view('Reports/inventory', [
            'title' => 'Inventory Report',
            'products' => $data,
            'categories' => $categories,
            'categoryId' => $categoryId,
            'breadcrumb' => ['Reports' => url('reports'), 'Inventory' => url('reports/inventory')],
        ]);
    }

    public function employees(): void
    {
        Auth::requirePermission('reports_view');
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));
        $employeeId = $this->request->get('employee_id');
        $data = $this->reportModel->getEmployeeReport($startDate, $endDate, $employeeId);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $db = Database::getInstance();
        $employees = $db->table('employees')->where('status', 'active')->get();

        $this->view('Reports/employees', [
            'title' => 'Employee Performance Report',
            'startDate' => $startDate,
            'endDate' => $endDate,
            'employees' => $data,
            'employeeList' => $employees,
            'employeeId' => $employeeId,
            'breadcrumb' => ['Reports' => url('reports'), 'Employees' => url('reports/employees')],
        ]);
    }

    public function customers(): void
    {
        Auth::requirePermission('reports_view');
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));
        $data = $this->reportModel->getCustomerReport($startDate, $endDate);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $this->view('Reports/customers', [
            'title' => 'Customer Report',
            'startDate' => $startDate,
            'endDate' => $endDate,
            'customers' => $data,
            'breadcrumb' => ['Reports' => url('reports'), 'Customers' => url('reports/customers')],
        ]);
    }

    public function appointments(): void
    {
        Auth::requirePermission('reports_view');
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));
        $status = $this->request->get('status');
        $data = $this->reportModel->getAppointmentReport($startDate, $endDate, $status);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $this->view('Reports/appointments', [
            'title' => 'Appointment Analysis Report',
            'startDate' => $startDate,
            'endDate' => $endDate,
            'appointments' => $data,
            'breadcrumb' => ['Reports' => url('reports'), 'Appointments' => url('reports/appointments')],
        ]);
    }

    public function cashFlow(): void
    {
        Auth::requirePermission('reports_view');
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));
        $data = $this->reportModel->getCashFlow($startDate, $endDate);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $this->view('Reports/cash_flow', [
            'title' => 'Cash Flow Report',
            'startDate' => $startDate,
            'endDate' => $endDate,
            'report' => $data,
            'breadcrumb' => ['Reports' => url('reports'), 'Cash Flow' => url('reports/cash-flow')],
        ]);
    }

    public function expenses(): void
    {
        Auth::requirePermission('reports_view');
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));
        $categoryId = $this->request->get('category_id');
        $data = $this->reportModel->getExpenseReport($startDate, $endDate, $categoryId);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $db = Database::getInstance();
        $categories = $db->table('expense_categories')->where('status', 'active')->get();

        $this->view('Reports/expenses', [
            'title' => 'Expense Report',
            'startDate' => $startDate,
            'endDate' => $endDate,
            'expenses' => $data,
            'categories' => $categories,
            'categoryId' => $categoryId,
            'breadcrumb' => ['Reports' => url('reports'), 'Expenses' => url('reports/expenses')],
        ]);
    }

    public function purchases(): void
    {
        Auth::requirePermission('reports_view');
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));
        $supplierId = $this->request->get('supplier_id');
        $data = $this->reportModel->getPurchaseReport($startDate, $endDate, $supplierId);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $db = Database::getInstance();
        $suppliers = $db->table('suppliers')->where('status', 'active')->get();

        $this->view('Reports/purchases', [
            'title' => 'Purchase Order Report',
            'startDate' => $startDate,
            'endDate' => $endDate,
            'purchases' => $data,
            'suppliers' => $suppliers,
            'supplierId' => $supplierId,
            'breadcrumb' => ['Reports' => url('reports'), 'Purchases' => url('reports/purchases')],
        ]);
    }

    public function stockMovement(): void
    {
        Auth::requirePermission('reports_view');
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));
        $productId = $this->request->get('product_id');
        $data = $this->reportModel->getStockMovement($startDate, $endDate, $productId);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $db = Database::getInstance();
        $products = $db->table('products')->where('deleted_at', 'IS', null)->get();

        $this->view('Reports/stock_movement', [
            'title' => 'Stock Movement Report',
            'startDate' => $startDate,
            'endDate' => $endDate,
            'movements' => $data,
            'products' => $products,
            'productId' => $productId,
            'breadcrumb' => ['Reports' => url('reports'), 'Stock Movement' => url('reports/stock-movement')],
        ]);
    }

    public function topServices(): void
    {
        Auth::requirePermission('reports_view');
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));
        $limit = (int)$this->request->get('limit', 10);
        $data = $this->reportModel->getTopServices($startDate, $endDate, $limit);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $this->view('Reports/top_services', [
            'title' => 'Top Services by Revenue',
            'startDate' => $startDate,
            'endDate' => $endDate,
            'services' => $data,
            'breadcrumb' => ['Reports' => url('reports'), 'Top Services' => url('reports/top-services')],
        ]);
    }

    public function topEmployees(): void
    {
        Auth::requirePermission('reports_view');
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));
        $limit = (int)$this->request->get('limit', 10);
        $data = $this->reportModel->getTopEmployees($startDate, $endDate, $limit);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $this->view('Reports/top_employees', [
            'title' => 'Top Employees by Revenue',
            'startDate' => $startDate,
            'endDate' => $endDate,
            'employees' => $data,
            'breadcrumb' => ['Reports' => url('reports'), 'Top Employees' => url('reports/top-employees')],
        ]);
    }

    public function topCustomers(): void
    {
        Auth::requirePermission('reports_view');
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));
        $limit = (int)$this->request->get('limit', 10);
        $data = $this->reportModel->getTopCustomers($startDate, $endDate, $limit);

        if ($this->isAjax()) {
            $this->json(['success' => true, 'data' => $data]);
            return;
        }

        $this->view('Reports/top_customers', [
            'title' => 'Top Customers by Spending',
            'startDate' => $startDate,
            'endDate' => $endDate,
            'customers' => $data,
            'breadcrumb' => ['Reports' => url('reports'), 'Top Customers' => url('reports/top-customers')],
        ]);
    }

    public function export(string $type): void
    {
        Auth::requirePermission('reports_export');

        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-t'));

        $data = match ($type) {
            'daily_sales' => $this->reportModel->getDailySales($this->request->get('date', date('Y-m-d'))),
            'monthly_sales' => $this->reportModel->getMonthlySales($this->request->get('month', date('m')), $this->request->get('year', date('Y'))),
            'yearly_sales' => $this->reportModel->getYearlySales($this->request->get('year', date('Y'))),
            'profit_loss' => $this->reportModel->getProfitLoss($startDate, $endDate),
            'inventory' => $this->reportModel->getInventoryReport($this->request->get('category_id')),
            'employees' => $this->reportModel->getEmployeeReport($startDate, $endDate, $this->request->get('employee_id')),
            'customers' => $this->reportModel->getCustomerReport($startDate, $endDate),
            'appointments' => $this->reportModel->getAppointmentReport($startDate, $endDate, $this->request->get('status')),
            'cash_flow' => $this->reportModel->getCashFlow($startDate, $endDate),
            'expenses' => $this->reportModel->getExpenseReport($startDate, $endDate, $this->request->get('category_id')),
            'purchases' => $this->reportModel->getPurchaseReport($startDate, $endDate, $this->request->get('supplier_id')),
            'stock_movement' => $this->reportModel->getStockMovement($startDate, $endDate, $this->request->get('product_id')),
            'top_services' => $this->reportModel->getTopServices($startDate, $endDate, 100),
            'top_employees' => $this->reportModel->getTopEmployees($startDate, $endDate, 100),
            'top_customers' => $this->reportModel->getTopCustomers($startDate, $endDate, 100),
            default => [],
        };

        $filename = $type . '_' . date('Ymd') . '.csv';

        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Pragma: no-cache');
        header('Expires: 0');

        $output = fopen('php://output', 'w');

        fwrite($output, "\xEF\xBB\xBF");

        $this->writeCsvHeader($output, $type);
        $this->writeCsvData($output, $type, $data);

        fclose($output);
        exit;
    }

    private function writeCsvHeader($output, string $type): void
    {
        $headers = match ($type) {
            'daily_sales' => ['Invoice #', 'Customer', 'Service', 'Employee', 'Time', 'Total', 'Payment Method', 'Status'],
            'monthly_sales' => ['Date', 'Invoices', 'Total Sales', 'Discounts', 'Net Total', 'Payment Method'],
            'yearly_sales' => ['Month', 'Invoices', 'Total Sales', 'Net Total', 'Growth'],
            'profit_loss' => ['Category', 'Amount'],
            'inventory' => ['Product', 'Category', 'SKU', 'Quantity', 'Reorder Level', 'Unit Cost', 'Total Value'],
            'employees' => ['Employee', 'Appointments', 'Services', 'Revenue', 'Commission', 'Rating'],
            'customers' => ['Customer', 'Email', 'Phone', 'Visits', 'Total Spent', 'Last Visit'],
            'appointments' => ['Date', 'Time', 'Customer', 'Service', 'Employee', 'Status', 'Total'],
            'cash_flow' => ['Date', 'Description', 'Type', 'Category', 'Payment Method', 'Amount'],
            'expenses' => ['Date', 'Description', 'Category', 'Amount', 'Payment Method', 'Reference'],
            'purchases' => ['PO #', 'Supplier', 'Date', 'Items', 'Total', 'Status'],
            'stock_movement' => ['Date', 'Product', 'Type', 'Quantity', 'Reference', 'User'],
            'top_services' => ['Service', 'Total Bookings', 'Total Revenue', 'Average Price'],
            'top_employees' => ['Employee', 'Appointments', 'Services', 'Total Revenue', 'Commission'],
            'top_customers' => ['Customer', 'Visits', 'Total Spent', 'Average per Visit', 'Last Visit'],
            default => ['Field', 'Value'],
        };
        fputcsv($output, $headers);
    }

    private function writeCsvData($output, string $type, array $data): void
    {
        foreach ($data as $row) {
            $row = (array)$row;
            $values = match ($type) {
                'daily_sales' => [
                    $row['invoice_number'] ?? '',
                    ($row['customer_first_name'] ?? '') . ' ' . ($row['customer_last_name'] ?? ''),
                    $row['service_name'] ?? '',
                    ($row['employee_first_name'] ?? '') . ' ' . ($row['employee_last_name'] ?? ''),
                    $row['start_time'] ?? '',
                    number_format((float)($row['total'] ?? 0), 2),
                    $row['payment_method'] ?? '',
                    $row['status'] ?? '',
                ],
                'inventory' => [
                    $row['product_name'] ?? $row['name'] ?? '',
                    $row['category_name'] ?? '',
                    $row['sku'] ?? '',
                    $row['quantity'] ?? 0,
                    $row['reorder_level'] ?? 0,
                    number_format((float)($row['unit_cost'] ?? 0), 2),
                    number_format((float)($row['total_value'] ?? 0), 2),
                ],
                'monthly_sales' => [
                    $row['date'] ?? '',
                    $row['total_invoices'] ?? 0,
                    number_format((float)($row['total_sales'] ?? 0), 2),
                    number_format((float)($row['total_discounts'] ?? 0), 2),
                    number_format((float)($row['net_total'] ?? 0), 2),
                    $row['payment_method'] ?? '',
                ],
                'yearly_sales' => [
                    $row['month'] ?? '',
                    $row['total_invoices'] ?? 0,
                    number_format((float)($row['total_sales'] ?? 0), 2),
                    number_format((float)($row['net_total'] ?? 0), 2),
                    ($row['growth'] ?? 0) . '%',
                ],
                'profit_loss' => [
                    $row['category'] ?? $row['type'] ?? '',
                    number_format((float)($row['amount'] ?? 0), 2),
                ],
                'employees' => [
                    ($row['first_name'] ?? '') . ' ' . ($row['last_name'] ?? ''),
                    $row['total_appointments'] ?? 0,
                    $row['total_services'] ?? 0,
                    number_format((float)($row['total_revenue'] ?? 0), 2),
                    number_format((float)($row['total_commission'] ?? 0), 2),
                    $row['avg_rating'] ?? '-',
                ],
                'customers' => [
                    ($row['first_name'] ?? '') . ' ' . ($row['last_name'] ?? ''),
                    $row['email'] ?? '',
                    $row['phone'] ?? '',
                    $row['total_visits'] ?? 0,
                    number_format((float)($row['total_spent'] ?? 0), 2),
                    $row['last_visit'] ?? '-',
                ],
                'appointments' => [
                    $row['date'] ?? '',
                    $row['start_time'] ?? '',
                    ($row['customer_first_name'] ?? '') . ' ' . ($row['customer_last_name'] ?? ''),
                    $row['service_name'] ?? '',
                    ($row['employee_first_name'] ?? '') . ' ' . ($row['employee_last_name'] ?? ''),
                    $row['status'] ?? '',
                    number_format((float)($row['total'] ?? 0), 2),
                ],
                'cash_flow' => [
                    $row['date'] ?? '',
                    $row['description'] ?? '',
                    $row['type'] ?? '',
                    $row['category'] ?? '',
                    $row['payment_method'] ?? '',
                    number_format((float)($row['amount'] ?? 0), 2),
                ],
                'expenses' => [
                    $row['date'] ?? '',
                    $row['description'] ?? '',
                    $row['category_name'] ?? '',
                    number_format((float)($row['amount'] ?? 0), 2),
                    $row['payment_method'] ?? '',
                    $row['reference'] ?? '',
                ],
                'purchases' => [
                    $row['po_number'] ?? '',
                    $row['supplier_name'] ?? '',
                    $row['order_date'] ?? '',
                    $row['total_items'] ?? 0,
                    number_format((float)($row['total'] ?? 0), 2),
                    $row['status'] ?? '',
                ],
                'stock_movement' => [
                    $row['created_at'] ?? '',
                    $row['product_name'] ?? '',
                    $row['type'] ?? '',
                    $row['quantity'] ?? 0,
                    $row['reference'] ?? '',
                    $row['user_name'] ?? '',
                ],
                'top_services' => [
                    $row['name'] ?? '',
                    $row['total_count'] ?? 0,
                    number_format((float)($row['total_revenue'] ?? 0), 2),
                    number_format((float)($row['avg_price'] ?? 0), 2),
                ],
                'top_employees' => [
                    ($row['first_name'] ?? '') . ' ' . ($row['last_name'] ?? ''),
                    $row['total_appointments'] ?? 0,
                    $row['total_services'] ?? 0,
                    number_format((float)($row['total_revenue'] ?? 0), 2),
                    number_format((float)($row['total_commission'] ?? 0), 2),
                ],
                'top_customers' => [
                    ($row['first_name'] ?? '') . ' ' . ($row['last_name'] ?? ''),
                    $row['total_visits'] ?? 0,
                    number_format((float)($row['total_spent'] ?? 0), 2),
                    number_format((float)($row['avg_per_visit'] ?? 0), 2),
                    $row['last_visit'] ?? '-',
                ],
                default => array_values($row),
            };
            fputcsv($output, $values);
        }
    }
}
