<?php
namespace App\Modules\HR\Reports\Exports;

use App\Modules\HR\Reports\Exports\Concerns\ProfessionalExcelStyles;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithColumnWidths;
use Maatwebsite\Excel\Concerns\WithStyles;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;

class AdditionDeductionDetailsExport implements FromCollection, WithHeadings, WithColumnWidths, WithStyles, WithTitle, WithEvents
{
    use ProfessionalExcelStyles;

    protected $employees;
    protected $dynamicColumns;

    public function __construct($data)
    {
        $this->employees      = $data['employees'];
        $this->dynamicColumns = $data['dynamicColumns'];
    }

    public function title(): string { return 'Addition & Deduction Details'; }

    public function headings(): array
    {
        $h = ['#', 'Emp Code', 'EPF No', 'Name', 'Department', 'Designation'];
        foreach ($this->dynamicColumns as $col) {
            $h[] = $col['name'];
        }
        return $h;
    }

    public function collection()
    {
        return $this->employees->values()->map(function ($emp, $i) {
            $row = [
                $i + 1,
                $emp->employee_code,
                $emp->epf_no,
                trim($emp->first_name . ' ' . ($emp->middle_name ?? '') . ' ' . $emp->last_name),
                optional($emp->department)->name,
                optional($emp->designation)->name,
            ];

            foreach ($this->dynamicColumns as $col) {
                if ($col['type'] === 'addition') {
                    $v = $emp->additions->where('addition_id', $col['id'])->first();
                } else {
                    $v = $emp->deductions->where('deduction_id', $col['id'])->first();
                }
                $row[] = $v ? (float) $v->amount : 0;
            }

            return $row;
        });
    }

    public function columnWidths(): array
    {
        $widths = [];
        $fixedWidths = [5, 13, 12, 30, 22, 22];
        foreach ($fixedWidths as $i => $w) {
            $widths[Coordinate::stringFromColumnIndex($i + 1)] = $w;
        }
        $dynCount = $this->dynamicColumns->count();
        for ($i = 0; $i < $dynCount; $i++) {
            $widths[Coordinate::stringFromColumnIndex(7 + $i)] = 16;
        }
        return $widths;
    }

    public function styles(Worksheet $sheet)
    {
        $lastRow  = $this->employees->count() + 1;
        $dynCount = $this->dynamicColumns->count();
        $lastCol  = Coordinate::stringFromColumnIndex(6 + $dynCount);

        $rightCols = [];
        for ($c = 7; $c <= 6 + $dynCount; $c++) {
            $rightCols[] = Coordinate::stringFromColumnIndex($c);
        }

        $this->applyStyles($sheet, $lastRow, $lastCol, ['A'], $rightCols);
        return [];
    }

    public function registerEvents(): array
    {
        return [
            AfterSheet::class => function (AfterSheet $event) {
                $sheet    = $event->sheet->getDelegate();
                $lastRow  = $this->employees->count() + 1;
                $dynCount = $this->dynamicColumns->count();

                if ($dynCount === 0 || $lastRow < 2) return;

                $firstCol = Coordinate::stringFromColumnIndex(7);
                $lastCol  = Coordinate::stringFromColumnIndex(6 + $dynCount);

                $sheet->getStyle("{$firstCol}2:{$lastCol}{$lastRow}")
                    ->getNumberFormat()
                    ->setFormatCode('#,##0.00;-#,##0.00;"-"');
            },
        ];
    }
}
