<?php

namespace App\Exports;

use Carbon\Carbon;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithStyles;
use Maatwebsite\Excel\Events\AfterSheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Alignment;

class LeaveManagementExport implements FromArray, WithHeadings, WithStyles, WithEvents
{
    protected $data;
    protected $year;

    public function __construct($data)
    {
        $this->data = $data;
        $this->year = Carbon::now()->year;
    }

    public function headings(): array
    {
        $months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
        return array_merge(
            ['No.', 'User'],
            $months,
            ['Total', 'Off', 'Remaining', 'Notes']
        );
    }

    public function array(): array
    {
        $headers = $this->headings(); // Lấy tiêu đề

        $rows = [];
        $stt = 0;
        foreach ($this->data as $index => $user) {
            $totalDayOff = 0;
            $totalDayLeave = $user['leaveDay']['ld_day'] + $user['leaveDay']['ld_date_additional'];

            // Tính tổng ngày nghỉ theo tháng
            $monthlyLeaves = array_fill(1, 12, 0);
            foreach ($user['monthlyLeaveDays'] as $leaveDay) {
                $monthlyLeaves[$leaveDay['month']] += $leaveDay['leave_days'];
                $totalDayOff += $leaveDay['leave_days'];
            }

            // Tạo dòng dữ liệu
            $row = [
                $stt + 1,
                $user['user']['name']
            ];

            // Thêm dữ liệu các tháng
            for ($month = 1; $month <= 12; $month++) {
                $row[] = $monthlyLeaves[$month] ?: '';
            }

            // Thêm tổng số ngày
            $row[] = $totalDayLeave;
            $row[] = $totalDayOff;
            $row[] = $totalDayLeave - $totalDayOff;
            $row[] = $user['leaveDay']['ld_note'] ?? '';

            $rows[] = $row;
            $stt++;
        }

        return array_merge([$headers], $rows); // Thêm tiêu đề vào đầu mảng
    }

    public function registerEvents(): array
    {
        return [
            AfterSheet::class => function(AfterSheet $event) {
                $sheet = $event->sheet->getDelegate();
                $lastRow = count($this->data) + 2;
                $noteColumn = 'R'; // Cột Notes

                // Xử lý đặc biệt cho cột Notes
                $sheet->getStyle("{$noteColumn}3:{$noteColumn}{$lastRow}")
                    ->getAlignment()
                    ->setWrapText(true)
                    ->setVertical(Alignment::VERTICAL_TOP)
                    ->setHorizontal(Alignment::HORIZONTAL_LEFT);

                // Tắt auto-size cho cột Notes và set độ rộng cố định
                $sheet->getColumnDimension($noteColumn)
                    ->setAutoSize(false)
                    ->setWidth(60);

                // Tự động điều chỉnh chiều cao cho từng dòng có nội dung
                for ($row = 3; $row <= $lastRow; $row++) {
                    $cellValue = $sheet->getCell($noteColumn . $row)->getValue();
                    if (!empty($cellValue)) {
                        // Tính toán chiều cao dựa trên nội dung
                        $sheet->getRowDimension($row)->setRowHeight(-1);
                        
                        // Tính toán lại chiều cao dựa trên số dòng trong nội dung
                        $lineCount = substr_count($cellValue, "\n") + 1;
                        $minHeight = max(30, $lineCount * 15); // 15 pixels cho mỗi dòng
                        
                        // Lấy chiều cao hiện tại sau khi auto-size
                        $currentHeight = $sheet->getRowDimension($row)->getRowHeight();
                        
                        // Nếu chiều cao tự động nhỏ hơn chiều cao tối thiểu, sử dụng chiều cao tối thiểu
                        if ($currentHeight < $minHeight) {
                            $sheet->getRowDimension($row)->setRowHeight($minHeight);
                        }
                    } else {
                        $sheet->getRowDimension($row)->setRowHeight(30);
                    }
                }

                // Refresh các tính toán của Excel
                $sheet->calculateColumnWidths();
            },
        ];
    }

    public function styles(Worksheet $sheet)
    {
        $lastRow = count($this->data) + 2;
        $lastColumn = 'R';

        // Thêm và style title
        $sheet->mergeCells("A1:{$lastColumn}1");
        $sheet->setCellValue('A1', "DANH SÁCH NGÀY NGHỈ NĂM {$this->year}");
        $sheet->getStyle("A1:{$lastColumn}1")->applyFromArray([
            'font' => [
                'bold' => true,
                'size' => 14
            ],
            'alignment' => [
                'horizontal' => Alignment::HORIZONTAL_CENTER,
                'vertical' => Alignment::VERTICAL_CENTER
            ]
        ]);

        // Style cho header (dời xuống row 2)
        $sheet->getStyle("A2:{$lastColumn}2")->applyFromArray([
            'font' => ['bold' => true],
            'alignment' => [
                'horizontal' => Alignment::HORIZONTAL_CENTER,
                'vertical' => Alignment::VERTICAL_CENTER
            ]
        ]);

        // Style cho toàn bộ bảng (bắt đầu từ row 1)
        $sheet->getStyle("A1:{$lastColumn}{$lastRow}")->applyFromArray([
            'borders' => [
                'allBorders' => [
                    'borderStyle' => Border::BORDER_THIN
                ]
            ],
            'alignment' => [
                'vertical' => Alignment::VERTICAL_CENTER
            ]
        ]);

        // Căn giữa cho các cột số liệu (điều chỉnh range bắt đầu từ row 3)
        for ($col = 'C'; $col <= 'P'; $col++) {
            $sheet->getStyle("{$col}3:{$col}{$lastRow}")
                ->getAlignment()
                ->setHorizontal(Alignment::HORIZONTAL_CENTER);
        }

        // Set độ rộng cột
        $sheet->getColumnDimension('A')->setWidth(5);  // No.
        $sheet->getColumnDimension('B')->setWidth(30); // User
        // Các tháng
        for ($i = 'C'; $i <= 'N'; $i++) {
            $sheet->getColumnDimension($i)->setWidth(8);
        }
        $sheet->getColumnDimension('O')->setWidth(8);  // Total
        $sheet->getColumnDimension('P')->setWidth(8);  // Off
        $sheet->getColumnDimension('Q')->setWidth(12); // Remaining
        $sheet->getColumnDimension('R')->setWidth(30); // Notes

        // Điều chỉnh style cho cột Notes
        $sheet->getStyle("R3:R{$lastRow}")
            ->getAlignment()
            ->setHorizontal(Alignment::HORIZONTAL_LEFT)
            ->setVertical(Alignment::VERTICAL_TOP)
            ->setWrapText(true);

        return $sheet;
    }
} 