<?php

namespace Portal\Mileage\Exports;

use Portal\Mileage\Model\Claim;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithStyles;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;

class ClaimsExport implements FromCollection, WithHeadings, WithMapping, ShouldAutoSize, WithStyles
{
    private const DATA_START_ROW = 7;

    protected $user;
    protected $claims;

    public function __construct($user = null, $claims = null)
    {
        $this->user = $user;
        $this->claims = $claims;
    }

    public function collection(): Collection
    {
        // Only Disemak claims should be exported
        return $this->claims->where('status', 'Disemak') ?? collect();
    }

    public function headings(): array
    {
        $roleName = $this->user?->roles?->first()?->name ?? '-';

        return [
            ['BORANG TUNTUTAN PERJALANAN'],
            [''],
            [
                'Nama Staf:', $this->user->name ?? '-',
                'Peranan:', $roleName,
            ],
            [
                'Syarikat:', '3F RESOURCES SDN BHD',
                'Tarikh:', Carbon::now()->format('d/m/Y'),
            ],
            [''],
            [
                'Tarikh',
                'Butiran Tuntutan',
                'Dari',
                'Ke',
                'Jumlah KM (Hari)',
                'Tol (RM)',
                'Lain-lain (RM)',
            ],
        ];
    }

    public function map($claim): array
    {
        return [
            Carbon::parse($claim->claim_date)->format('d/m/Y'),
            $claim->description ?? '-',
            $claim->distance_from ?? '-',
            $claim->distance_to ?? '-',
            number_format($claim->total_mileage ?? 0, 2),
            number_format($claim->toll_amount ?? 0, 2),
            number_format($claim->others_amount ?? 0, 2),
        ];
    }

    public function styles(Worksheet $sheet): array
    {
        $lastDataRow = $sheet->getHighestRow();
        $totalRow = $lastDataRow + 2;
        $signRow = $totalRow + 3;

        // Header Formatting
        $sheet->mergeCells('A1:G1');
        $sheet->getStyle('A1')->applyFromArray([
            'font' => ['bold' => true, 'size' => 14],
            'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER],
        ]);

        // Table Header Formatting
        $sheet->getStyle('A6:G6')->applyFromArray([
            'font' => ['bold' => true],
            'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER],
            'fill' => [
                'fillType' => Fill::FILL_SOLID,
                'startColor' => ['argb' => 'FFEFEFEF'],
            ],
        ]);

        // Align numeric columns to the right
        $dataRange = 'E' . self::DATA_START_ROW . ':G' . $lastDataRow;
        $sheet->getStyle($dataRange)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT);

        // Total Row Formatting
        $sheet->setCellValue("A{$totalRow}", 'Jumlah Keseluruhan:');
        $sheet->mergeCells("A{$totalRow}:D{$totalRow}");
        $sheet->setCellValue("E{$totalRow}", "=SUM(E" . self::DATA_START_ROW . ":E{$lastDataRow})");
        $sheet->setCellValue("F{$totalRow}", "=SUM(F" . self::DATA_START_ROW . ":F{$lastDataRow})");
        $sheet->setCellValue("G{$totalRow}", "=SUM(G" . self::DATA_START_ROW . ":G{$lastDataRow})");
        $sheet->getStyle("A{$totalRow}:G{$totalRow}")->getFont()->setBold(true);

        // Notes Section Formatting
        $sheet->setCellValue("A{$signRow}", 'Seksyen Pengiraan:');
        $sheet->setCellValue("A" . ($signRow + 1), '• Tuntutan bermula selepas 40KM pertama setiap hari.');
        $sheet->setCellValue("A" . ($signRow + 2), '• Kadar (Kereta): RM0.55/km (<500km), RM0.50/km (>500km).');
        $sheet->setCellValue("A" . ($signRow + 3), '• Kadar (Motosikal): RM0.30/km.');
        $sheet->getStyle("A{$signRow}")->getFont()->setBold(true);

        // Signature Section Formatting
        $signStart = $signRow + 6;

        // Disahkan oleh (Project Manager / HOD) with Project name or description
        $approvedList = $this->claims
            ->whereNotNull('approved_by')
            ->map(function ($claim) {
                $user = $claim->approvedBy?->name ?? '-';
                $role = $claim->approvedBy?->roles?->first()?->name ?? 'Penyemak';
                
                // If project exists, use project name, else fallback to description
                $project = $claim->project ? $claim->project->p_project_description : "(Butiran Projek: " . ($claim->description ?? '-') . ")";
                
                return "{$user} - {$role} ({$project})";  // Project name in parentheses
            })
            ->unique()
            ->implode("\n\n");

        // Diluluskan oleh (Project Director / BOD)
        $reviewedList = $this->claims
            ->whereNotNull('reviewed_by')
            ->map(function ($claim) {
                $user = $claim->reviewedBy?->name ?? '-';
                $role = $claim->reviewedBy?->roles?->first()?->name ?? 'Pelulus';
                $project = $claim->project ? $claim->project->name : "(Butiran Projek: " . ($claim->description ?? '-') . ")";
                return "{$user} - {$role} {$project}";
            })
            ->unique()
            ->implode("\n\n");

        // Disediakan oleh (Staff) with Role
        $preparedBy = $this->user->name ?? '-';
        $preparedRole = $this->user->roles->first()->name ?? 'Staf';

        // Write to Excel Cells
        $sheet->setCellValue("A{$signStart}", 'Disediakan oleh:');
        $sheet->setCellValue("A" . ($signStart + 1), "{$preparedBy}\n({$preparedRole})");
        $sheet->getStyle("A" . ($signStart + 1))->getAlignment()->setWrapText(true);

        $sheet->setCellValue("C{$signStart}", 'Disahkan oleh:');
        $sheet->setCellValue("C" . ($signStart + 1), $approvedList ?: '-');
        $sheet->getStyle("C" . ($signStart + 1))->getAlignment()->setWrapText(true);

        $sheet->setCellValue("E{$signStart}", 'Diluluskan oleh:');
        $sheet->setCellValue("E" . ($signStart + 1), $reviewedList ?: '-');
        $sheet->getStyle("E" . ($signStart + 1))->getAlignment()->setWrapText(true);

        $sheet->getStyle("A{$signStart}:E{$signStart}")->getFont()->setBold(true);

        return [];
    }
}
