<?php

namespace App\Services\Import;

use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;

class ExcelParser implements FileParserInterface
{
    protected static array $supportedExtensions = ['xlsx', 'xls'];

    /**
     * Parse the Excel file and return all data
     */
    public function parse(string $filePath, array $options = []): array
    {
        $headerRow = $options['header_row'] ?? 0;
        $dataStartRow = $options['data_start_row'] ?? 1;
        
        $spreadsheet = IOFactory::load($filePath);
        $worksheet = $spreadsheet->getActiveSheet();
        
        $data = [];
        $headers = [];
        
        foreach ($worksheet->getRowIterator() as $rowIndex => $row) {
            $rowData = [];
            $cellIterator = $row->getCellIterator();
            $cellIterator->setIterateOnlyExistingCells(false);
            
            foreach ($cellIterator as $cell) {
                $value = $cell->getCalculatedValue();
                // Tratar valores de data do Excel
                if (\PhpOffice\PhpSpreadsheet\Shared\Date::isDateTime($cell)) {
                    try {
                        $dateValue = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
                        $value = $dateValue->format('d/m/Y');
                    } catch (\Exception $e) {
                        // Manter valor original se não conseguir converter
                    }
                }
                $rowData[] = $value;
            }
            
            // Linha de cabeçalho (1-indexed no PhpSpreadsheet)
            if ($rowIndex === $headerRow + 1) {
                $headers = $rowData;
                continue;
            }
            
            // Pular linhas antes dos dados
            if ($rowIndex < $dataStartRow + 1) {
                continue;
            }
            
            // Verificar se a linha não está completamente vazia
            $nonEmpty = array_filter($rowData, fn($v) => $v !== null && $v !== '');
            if (!empty($nonEmpty)) {
                $data[] = $rowData;
            }
        }
        
        return [
            'headers' => $headers,
            'data' => $data,
            'total_rows' => count($data),
        ];
    }

    /**
     * Get headers from the Excel file
     */
    public function getHeaders(string $filePath, array $options = []): array
    {
        $headerRow = $options['header_row'] ?? 0;
        
        $spreadsheet = IOFactory::load($filePath);
        $worksheet = $spreadsheet->getActiveSheet();
        
        $headers = [];
        $row = $worksheet->getRowIterator($headerRow + 1, $headerRow + 1)->current();
        
        if ($row) {
            $cellIterator = $row->getCellIterator();
            $cellIterator->setIterateOnlyExistingCells(false);
            
            foreach ($cellIterator as $cell) {
                $headers[] = $cell->getCalculatedValue();
            }
        }
        
        // Remover valores nulos do final
        while (!empty($headers) && (end($headers) === null || end($headers) === '')) {
            array_pop($headers);
        }
        
        return $headers;
    }

    /**
     * Get preview data (first N rows)
     */
    public function getPreview(string $filePath, int $rows = 10, array $options = []): array
    {
        $spreadsheet = IOFactory::load($filePath);
        $worksheet = $spreadsheet->getActiveSheet();
        
        $preview = [];
        $rowCount = 0;
        
        foreach ($worksheet->getRowIterator() as $row) {
            if ($rowCount >= $rows) {
                break;
            }
            
            $rowData = [];
            $cellIterator = $row->getCellIterator();
            $cellIterator->setIterateOnlyExistingCells(false);
            
            foreach ($cellIterator as $cell) {
                $value = $cell->getCalculatedValue();
                // Tratar valores de data do Excel
                if (\PhpOffice\PhpSpreadsheet\Shared\Date::isDateTime($cell)) {
                    try {
                        $dateValue = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
                        $value = $dateValue->format('d/m/Y');
                    } catch (\Exception $e) {
                        // Manter valor original
                    }
                }
                $rowData[] = $value;
            }
            
            // Remover valores nulos do final
            while (!empty($rowData) && (end($rowData) === null || end($rowData) === '')) {
                array_pop($rowData);
            }
            
            $preview[] = [
                'row_index' => $rowCount,
                'data' => $rowData,
            ];
            
            $rowCount++;
        }
        
        // Contar total de linhas
        $totalRows = $worksheet->getHighestRow();
        
        return [
            'preview' => $preview,
            'total_rows' => $totalRows,
            'columns_count' => !empty($preview) ? count($preview[0]['data']) : 0,
        ];
    }

    /**
     * Check if parser supports the extension
     */
    public static function supports(string $extension): bool
    {
        return in_array(strtolower($extension), self::$supportedExtensions);
    }
}
