<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Models\BiModel;
use Core\Request;
use Core\Auth;

final class BiController extends BaseController
{
    private BiModel $model;

    public function __construct()
    {
        parent::__construct();
        Auth::requireLogin();
        $this->requirePermission('report.bi');
        $this->model = new BiModel();
    }

    // ── Overview ──────────────────────────────────────────────────────────────

    public function overview(): void
    {
        [$from, $to] = $this->dateRange();

        $this->view('reports.bi_overview', [
            'title'        => 'BI Overview',
            'from'         => $from,
            'to'           => $to,
            'summary'      => $this->model->summary($from, $to),
            'prevSummary'  => $this->model->summaryPrev($from, $to),
            'daily'        => $this->model->dailyTrend($from, $to),
            'paymentSplit' => $this->model->paymentSplit($from, $to),
            'typeSplit'    => $this->model->orderTypeSplit($from, $to),
            'newCustomers' => $this->model->newCustomersThisPeriod($from, $to),
            'monthly'      => $this->model->monthlyRevenue(6),
        ]);
    }

    // ── Revenue analytics ─────────────────────────────────────────────────────

    public function revenue(): void
    {
        [$from, $to] = $this->dateRange();

        $this->view('reports.bi_revenue', [
            'title'      => 'Revenue Analytics',
            'from'       => $from,
            'to'         => $to,
            'summary'    => $this->model->summary($from, $to),
            'byHour'     => $this->model->revenueByHour($from, $to),
            'byDow'      => $this->model->revenueByDayOfWeek($from, $to),
            'components' => $this->model->revenueComponents($from, $to),
            'monthly'    => $this->model->monthlyRevenue(6),
        ]);
    }

    // ── Category performance ──────────────────────────────────────────────────

    public function category(): void
    {
        [$from, $to] = $this->dateRange();

        $this->view('reports.bi_category', [
            'title'    => 'Category Performance',
            'from'     => $from,
            'to'       => $to,
            'summary'  => $this->model->summary($from, $to),
            'cats'     => $this->model->categoryPerformance($from, $to),
            'topItems' => $this->model->topItemsPerCategory($from, $to),
        ]);
    }

    // ── Peak hours ────────────────────────────────────────────────────────────

    public function peakHours(): void
    {
        [$from, $to] = $this->dateRange();

        $this->view('reports.bi_peak_hours', [
            'title'        => 'Peak Hours',
            'from'         => $from,
            'to'           => $to,
            'heatmap'      => $this->model->peakHeatmap($from, $to),
            'busiestHour'  => $this->model->busiestHour($from, $to),
            'busiestDay'   => $this->model->busiestDay($from, $to),
            'byHour'       => $this->model->revenueByHour($from, $to),
            'byDow'        => $this->model->revenueByDayOfWeek($from, $to),
        ]);
    }

    // ── Cancellations ─────────────────────────────────────────────────────────

    public function cancellations(): void
    {
        [$from, $to] = $this->dateRange();
        $summary     = $this->model->summary($from, $to);

        $this->view('reports.bi_cancellations', [
            'title'       => 'Cancellation Analysis',
            'from'        => $from,
            'to'          => $to,
            'summary'     => $summary,
            'byHour'      => $this->model->cancellationByHour($from, $to),
            'byDay'       => $this->model->cancellationByDay($from, $to),
            'guestVsReg'  => $this->model->cancellationGuestVsRegistered($from, $to),
        ]);
    }

    // ── Rider performance ─────────────────────────────────────────────────────

    public function riders(): void
    {
        [$from, $to] = $this->dateRange();

        $rows = $this->model->riderPerformance($from, $to);

        if (Request::get('export') === 'csv') {
            $this->exportCsv('rider_performance_' . $from . '_' . $to,
                ['Rider', 'Phone', 'Assigned', 'Delivered', 'Cancelled', 'Revenue Handled'],
                array_map(fn($r) => [
                    $r['rider_name'], $r['phone'],
                    $r['total_assigned'], $r['delivered'], $r['cancelled'],
                    number_format((float)$r['revenue_handled'], 2),
                ], $rows)
            );
        }

        $this->view('reports.bi_riders', [
            'title'  => 'Rider Performance',
            'from'   => $from,
            'to'     => $to,
            'riders' => $rows,
        ]);
    }

    // ── Retention ─────────────────────────────────────────────────────────────

    public function retention(): void
    {
        [$from, $to] = $this->dateRange();

        $this->view('reports.bi_retention', [
            'title'        => 'Customer Retention',
            'from'         => $from,
            'to'           => $to,
            'newVsReturn'  => $this->model->newVsReturning($from, $to),
            'tierBreakdown'=> $this->model->tierBreakdown(),
            'tierRevenue'  => $this->model->tierRevenue(),
            'repeatRate'   => $this->model->repeatOrderRate(),
            'churned'      => $this->model->churnedCustomers(),
            'newCustomers' => $this->model->newCustomersThisPeriod($from, $to),
        ]);
    }

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

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

    private function exportCsv(string $name, array $headers, array $rows): never
    {
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="' . $name . '.csv"');
        $fp = fopen('php://output', 'w');
        fputcsv($fp, $headers);
        foreach ($rows as $r) fputcsv($fp, $r);
        fclose($fp);
        exit;
    }
}
