<?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 TimekeepingExport implements FromArray, WithHeadings, WithStyles, WithEvents
{
    protected $data;
    protected $month;
    protected $year;
    protected $workingDays;
    protected $daysInMonth;

    public function __construct($data, $month, $year, $workingDays)
    {
        $this->data = $data;
        $this->month = $month;
        $this->year = $year;
        $this->workingDays = $workingDays;
        $this->daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
    }

    public function registerEvents(): array
    {
        return [
            AfterSheet::class => function(AfterSheet $event) {
                $sheet = $event->sheet->getDelegate();
                $lastRow = count($this->data) + 4;
                $noteColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($this->daysInMonth + 4);

                // Xử lý đặc biệt cho cột Notes
                $sheet->getStyle("{$noteColumn}5:{$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 = 5; $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 array(): array
    {
        // Lấy headers
        $headers = $this->headings();
        
        // Lấy dữ liệu người dùng
        $userRows = [];
        foreach ($this->data as $user) {
            $row = [
                $user['user']['name'] ?? 'Unknown',
                0, // Total days
                $this->workingDays, // Off days (initialize with working days)
            ];

            $totalDays = 0;
            // Add data for each day in month
            for ($day = 1; $day <= $this->daysInMonth; $day++) {
                $dayData = '';
                if (isset($user['history'])) {
                    foreach ($user['history'] as $history) {
                        if ($history['day'] === $day) {
                            $total = $history['total'] ?? 0;
                            if ($total >= 7 * 3600) {
                                $dayData = '1';
                                $totalDays += 1;
                            } else if ($total >= 3.5 * 3600) {
                                $dayData = '0.5';
                                $totalDays += 0.5;
                            }
                            break;
                        }
                    }
                }
                $row[] = $dayData;
            }
            
            // Update total and off days
            $row[1] = $totalDays;
            $row[2] = $this->workingDays - $totalDays;
            
            // Add Notes column with formatted content
            $notes = [];
            if (isset($user['history'])) {
                foreach ($user['history'] as $history) {
                    if (!empty($history['notes'])) {
                        $dayNotes = [];
                        foreach ($history['notes'] as $note) {
                            $dayNotes[] = "- {$note['reasonName']} ({$note['timeTypeName']}): {$note['note']}";
                        }
                        if (!empty($dayNotes)) {
                            $notes[] = "Day {$history['day']}:\n" . implode("\n", $dayNotes);
                        }
                    }
                }
            }
            $row[] = !empty($notes) ? implode("\n\n", $notes) : '';
            
            $userRows[] = $row;
        }

        return array_merge($headers, $userRows);
    }

    public function headings(): array
    {

        $firstRow = ['Day', '', ''];
        // Second row: Day of week
        $secondRow = ['', '', ''];

        $date = Carbon::create($this->year, $this->month, 1);
        
        for ($day = 1; $day <= $this->daysInMonth; $day++) {
            $firstRow[] = $day;
            $secondRow[] = $date->format('D');
            $date->addDay();
        }

        // Add Notes column
        $firstRow[] = 'Notes';
        $secondRow[] = '';

        return [$firstRow, $secondRow];
    }

    public function styles(Worksheet $sheet)
    {
        $lastColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($this->daysInMonth + 4);
        $lastRow = count($this->data) + 4;
        $noteColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($this->daysInMonth + 4);

        // Title and working days
        $sheet->mergeCells("A1:{$lastColumn}1");
        $sheet->setCellValue('A1', "DANH SÁCH CHẤM CÔNG THÁNG {$this->month} NĂM {$this->year}");
        $sheet->mergeCells("A2:{$lastColumn}2");
        $sheet->setCellValue('A2', "Số ngày làm việc: {$this->workingDays}");

        // Merge cells for "Day" title and set value
        $sheet->mergeCells("A3:C3");
        $sheet->setCellValue('A3', 'Day');

        // Set values for A4, B4, C4
        $sheet->setCellValue('A4', 'User');
        $sheet->setCellValue('B4', 'Total');
        $sheet->setCellValue('C4', 'Off');

        // Styling
        $sheet->getStyle("A1:{$lastColumn}1")->getFont()->setBold(true)->setSize(14);
        $sheet->getStyle("A2:{$lastColumn}2")->getFont()->setBold(true);
        $sheet->getStyle("A3:{$lastColumn}4")->getFont()->setBold(true);

        // Border style
        $borderStyle = [
            'borders' => [
                'allBorders' => [
                    'borderStyle' => Border::BORDER_THIN,
                ],
            ],
        ];

        // Apply borders to the data area
        $sheet->getStyle("A1:{$lastColumn}{$lastRow}")->applyFromArray($borderStyle);

        // Center align all cells except Notes column
        $sheet->getStyle("A1:{$lastColumn}{$lastRow}")
            ->getAlignment()
            ->setHorizontal(Alignment::HORIZONTAL_CENTER)
            ->setVertical(Alignment::VERTICAL_CENTER);

        // Left align Notes column và bật wrap text
        $sheet->getStyle("{$noteColumn}5:{$noteColumn}{$lastRow}")
            ->getAlignment()
            ->setHorizontal(Alignment::HORIZONTAL_LEFT)
            ->setVertical(Alignment::VERTICAL_TOP)
            ->setWrapText(true);

        // Set width for Note column - tăng độ rộng để hiển thị tốt hơn
        $sheet->getColumnDimension($noteColumn)->setWidth(60);

        // Tự động điều chỉnh chiều cao cho các dòng có nội dung Notes
        for ($row = 5; $row <= $lastRow; $row++) {
            $cellValue = $sheet->getCell($noteColumn . $row)->getValue();
            if (!empty($cellValue)) {
                // Đết chiều cao tự động
                $sheet->getRowDimension($row)->setRowHeight(-1);
                
                // Đảm bảo chiều cao tối thiểu
                $currentHeight = $sheet->getRowDimension($row)->getRowHeight();
                if ($currentHeight < 30) {
                    $sheet->getRowDimension($row)->setRowHeight(30);
                }
            } else {
                // Chiều cao mặc định cho các dòng không có note
                $sheet->getRowDimension($row)->setRowHeight(30);
            }
        }

        // Set column widths
        $sheet->getColumnDimension('A')->setWidth(30);
        $sheet->getColumnDimension('B')->setWidth(10);
        $sheet->getColumnDimension('C')->setWidth(10);
        for ($i = 4; $i <= $this->daysInMonth + 3; $i++) {
            $sheet->getColumnDimension(\PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i))->setWidth(5);
        }

        return [];
    }
} 