<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\BaseController;
use App\Core\Database;
use App\Core\Request;
use App\Core\Response;
use App\Helpers\AjaxResponse;
use App\Services\ExportService;
use App\Services\PdfExportService;
use App\Services\ReportService;
use App\Services\XlsxExportService;

/**
 * ReportController
 *
 * One page, one tab per report type named in the Phase 6 brief (Lead,
 * Customer, Revenue, Marketing, Campaign, Appointment, AI, Staff
 * Performance, System Logs) — all backed by the same ReportService the
 * AI Assistant's generate_report tool already uses, so "what the AI
 * can tell you" and "what the Reports page shows you" are always the
 * same numbers. Every tab supports CSV, Excel, and Print export.
 */
final class ReportController extends BaseController
{
    private const REPORT_TYPES = ['overview', 'leads', 'customers', 'revenue', 'marketing', 'appointments', 'ai', 'staff', 'system_logs'];

    public function index(Request $request): Response
    {
        $type = in_array($request->query('type'), self::REPORT_TYPES, true) ? $request->query('type') : 'overview';
        $businessLineId = $request->query('business_line_id') ? (int) $request->query('business_line_id') : null;
        $days = (int) $request->query('days', 30);

        $data = $this->buildReport($type, $businessLineId, $days);

        if ($request->isAjax() || $request->isJson()) {
            return AjaxResponse::success($data);
        }

        return $this->view('ai/reports', [
            'title' => 'Reports',
            'activeNav' => 'reports',
            'breadcrumbs' => [['Home', 'dashboard'], ['Reports', 'reports']],
            'type' => $type,
            'report' => $data,
            'businessLines' => Database::connection()->query('SELECT id, name FROM business_lines ORDER BY name')->fetchAll(),
            'days' => $days,
        ]);
    }

    public function export(Request $request, array $params): Response
    {
        $type = in_array($params['type'], self::REPORT_TYPES, true) ? $params['type'] : 'overview';
        $format = in_array($params['format'], ['csv', 'excel', 'pdf'], true) ? $params['format'] : 'csv';
        $businessLineId = $request->query('business_line_id') ? (int) $request->query('business_line_id') : null;
        $days = (int) $request->query('days', 30);

        $data = $this->buildReport($type, $businessLineId, $days);
        [$rows, $columns] = $this->flattenForExport($type, $data);

        $reportTitle = ucfirst(str_replace('_', ' ', $type)) . ' Report';
        $filename = "{$type}-report-" . date('Y-m-d');

        if ($format === 'pdf') {
            $subtitle = 'Last ' . $days . ' days' . ($businessLineId !== null ? '' : ' - All Businesses');
            $pdf = (new PdfExportService())->toPdf($rows, $columns, $reportTitle, $subtitle);

            return Response::html($pdf)
                ->withHeader('Content-Type', 'application/pdf')
                ->withHeader('Content-Disposition', "attachment; filename=\"{$filename}.pdf\"");
        }

        if ($format === 'excel') {
            $xlsx = (new XlsxExportService())->toXlsx($rows, $columns, $reportTitle);

            return Response::html($xlsx)
                ->withHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
                ->withHeader('Content-Disposition', "attachment; filename=\"{$filename}.xlsx\"");
        }

        return Response::html((new ExportService())->toCsv($rows, $columns))
            ->withHeader('Content-Type', 'text/csv; charset=UTF-8')
            ->withHeader('Content-Disposition', "attachment; filename=\"{$filename}.csv\"");
    }

    private function buildReport(string $type, ?int $businessLineId, int $days): array
    {
        $reports = new ReportService();

        return match ($type) {
            'leads' => $reports->leadsPipelineReport($businessLineId, $days),
            'customers' => $reports->customerReport($businessLineId, $days),
            'revenue' => $reports->revenueReport($businessLineId, $days),
            'marketing' => $reports->marketingReport($days),
            'appointments' => $reports->appointmentsReport($businessLineId, $days),
            'ai' => $reports->aiReport($days),
            'staff' => $reports->staffPerformanceReport($days),
            'system_logs' => $reports->systemLogsReport($days),
            default => $reports->overviewReport($businessLineId, $days),
        };
    }

    /** @return array{0: array, 1: array<string,string>} [rows, columns] shaped for ExportService. */
    private function flattenForExport(string $type, array $data): array
    {
        return match ($type) {
            'leads' => [$data['stages'], ['stage' => 'Stage', 'count' => 'Count', 'total_value' => 'Total Value']],
            'customers' => [$data['by_status'], ['status' => 'Status', 'count' => 'Count', 'total_lifetime_value' => 'Lifetime Value']],
            'marketing' => [$data['recent_campaigns'], ['name' => 'Campaign', 'recipients_count' => 'Recipients', 'opens_count' => 'Opens', 'clicks_count' => 'Clicks', 'sent_at' => 'Sent']],
            'appointments' => [$data['by_status'], ['status' => 'Status', 'count' => 'Count']],
            'ai' => [$data['conversations'], ['channel' => 'Channel', 'total' => 'Total', 'leads_captured' => 'Leads Captured', 'appointments_booked' => 'Booked', 'escalated_to_human' => 'Escalated']],
            'staff' => [$data['staff'], ['name' => 'Staff', 'leads_owned' => 'Leads Owned', 'leads_won' => 'Leads Won', 'appointments_completed' => 'Appointments Completed', 'conversations_handled' => 'Conversations Handled']],
            'system_logs' => [$data['by_category'], ['category' => 'Category', 'count' => 'Count']],
            default => [[$data['revenue'] ?? []], ['total_revenue' => 'Total Revenue', 'invoices_paid' => 'Invoices Paid']],
        };
    }
}
