<?php

namespace App\Http\Controllers\Admin;

use App\Exports\ReportExport;
use App\Http\Controllers\Controller;
use App\Services\ActivityLogService;
use App\Services\IcNumberService;
use App\Services\ReportService;
use App\Services\SettingService;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class ReportController extends Controller
{
    public function __construct(
        private readonly ReportService $reportService,
        private readonly SettingService $settingService,
        private readonly ActivityLogService $activityLogService,
        private readonly IcNumberService $icNumberService,
    ) {}

    public function index(Request $request): View
    {
        $type = $request->input('type', 'overall');
        $filters = $request->only(['date_from', 'date_to', 'category', 'name', 'participant_number']);

        $data = match ($type) {
            'downloaded' => $this->reportService->getDownloadedParticipants($filters)->paginate(20),
            'not_downloaded' => $this->reportService->getNotDownloadedParticipants($filters)->paginate(20),
            'history' => $this->reportService->getDownloadHistory($filters)->paginate(20),
            default => null,
        };

        return view('admin.reports.index', [
            'type' => $type,
            'filters' => $filters,
            'data' => $data,
            'stats' => $this->reportService->getOverallStats(
                $request->date('date_from'),
                $request->date('date_to'),
            ),
            'settings' => $this->settingService->all(),
        ]);
    }

    public function exportExcel(Request $request): BinaryFileResponse
    {
        $type = $request->input('type', 'downloaded');
        $filters = $request->only(['date_from', 'date_to', 'category', 'name', 'participant_number']);

        [$collection, $headings, $mapper] = $this->getExportData($type, $filters);

        $this->activityLogService->log('export', 'reports', "Eksport laporan Excel: {$type}");

        return Excel::download(
            new ReportExport($collection, $headings, $mapper),
            "laporan_{$type}_".now()->format('Ymd_His').'.xlsx'
        );
    }

    public function exportPdf(Request $request)
    {
        $type = $request->input('type', 'overall');
        $filters = $request->only(['date_from', 'date_to', 'category', 'name', 'participant_number']);

        [$collection, $headings] = $this->getExportData($type, $filters);

        $this->activityLogService->log('export', 'reports', "Eksport laporan PDF: {$type}");

        $pdf = Pdf::loadView('admin.reports.pdf', [
            'type' => $type,
            'headings' => $headings,
            'data' => $collection,
            'settings' => $this->settingService->all(),
            'stats' => $this->reportService->getOverallStats(),
            'generatedAt' => now(),
            'filters' => $filters,
        ]);

        return $pdf->download("laporan_{$type}_".now()->format('Ymd_His').'.pdf');
    }

    private function getExportData(string $type, array $filters): array
    {
        return match ($type) {
            'downloaded' => [
                $this->reportService->getDownloadedParticipants($filters)->get(),
                ['Nama Peserta', 'No. Peserta', 'Kategori', 'Muat Turun Pertama', 'Muat Turun Terakhir', 'Bilangan Muat Turun'],
                fn ($p) => [$p->full_name, $p->participant_number, $p->category, $p->first_downloaded_at?->format('d/m/Y H:i'), $p->last_downloaded_at?->format('d/m/Y H:i'), $p->download_count],
            ],
            'not_downloaded' => [
                $this->reportService->getNotDownloadedParticipants($filters)->get(),
                ['Nama Peserta', 'No. Peserta', 'Kategori', 'Tarikh Import'],
                fn ($p) => [$p->full_name, $p->participant_number, $p->category, $p->created_at?->format('d/m/Y H:i')],
            ],
            'history' => [
                $this->reportService->getDownloadHistory($filters)->get(),
                ['Nama Peserta', 'Tarikh', 'IP', 'Peranti', 'Browser', 'Status', 'Jenis'],
                fn ($d) => [$d->participant?->full_name, $d->downloaded_at?->format('d/m/Y H:i'), $d->ip_address, $d->device_type, $d->browser, $d->download_status, $d->download_type],
            ],
            default => [
                collect([$this->reportService->getOverallStats()]),
                ['Jumlah Peserta', 'Telah Muat Turun', 'Belum Muat Turun', 'Peratus', 'Jumlah Transaksi'],
                fn ($s) => [$s['total_participants'], $s['downloaded_participants'], $s['not_downloaded_participants'], $s['download_percentage'].'%', $s['total_transactions']],
            ],
        };
    }
}
