<?php

namespace App\Exports;

use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
use Maatwebsite\Excel\Concerns\WithStyles;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Events\AfterSheet;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;

class OctoparseSheet extends DefaultValueBinder implements
    FromArray,
    WithHeadings,
    WithTitle,
    ShouldAutoSize,
    WithColumnFormatting,
    WithStyles,
    WithEvents,
    WithCustomValueBinder,
    WithStrictNullComparison
{
    protected const MAX_COLUMN_WIDTH = 60;

    protected string $title;
    protected array $headings;
    protected array $rows;

    protected array $dateColumns;

    public function __construct(string $title, array $headings, array $rows, array $dateColumns = [])
    {
        $this->title       = $title;
        $this->headings    = $headings;
        $this->rows        = $rows;
        $this->dateColumns = $dateColumns;
    }

    public function array(): array
    {
        return $this->rows;
    }

    public function headings(): array
    {
        return $this->headings;
    }

    public function title(): string
    {
        return $this->title;
    }

    public function columnFormats(): array
    {
        return array_fill_keys($this->dateColumns, 'yyyy-mm-dd hh:mm');
    }

    public function styles(Worksheet $sheet): array
    {
        return [
            1 => [
                'font' => ['bold' => true, 'color' => ['argb' => 'FFFFFFFF']],
                'fill' => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['argb' => 'FF000000']],
            ],
        ];
    }

    public function registerEvents(): array
    {
        return [
            AfterSheet::class => function (AfterSheet $event) {
                $sheet = $event->sheet->getDelegate();
                $sheet->freezePane('A2');
                $sheet->setAutoFilter($sheet->calculateWorksheetDimension());

                $sheet->calculateColumnWidths();
                foreach ($sheet->getColumnDimensions() as $dimension) {
                    if ($dimension->getWidth() > self::MAX_COLUMN_WIDTH) {
                        $dimension->setAutoSize(false)->setWidth(self::MAX_COLUMN_WIDTH);
                    }
                }
            },
        ];
    }

    public function bindValue(Cell $cell, $value)
    {
        if (is_string($value)) {
            $cell->setValueExplicit($value, DataType::TYPE_STRING);

            return true;
        }

        return parent::bindValue($cell, $value);
    }
}
