<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
use Smalot\PdfParser\Parser;

class TestarExtracaoMares extends Command
{
    protected $signature = 'testar:mares {arquivo} {--debug}';
    protected $description = 'Testar a extração de dados de tábuas de marés com diagnóstico detalhado';

    public function handle()
    {
        $arquivo = $this->argument('arquivo');
        $debug = $this->option('debug');
        
        if (!Storage::disk('public')->exists($arquivo)) {
            $this->error("Arquivo não encontrado: $arquivo");
            $this->info("Arquivos disponíveis no storage público:");
            $arquivos = Storage::disk('public')->files('tabuas_mares');
            foreach ($arquivos as $arq) {
                $this->info(" - $arq");
            }
            return;
        }

        $caminhoCompleto = Storage::disk('public')->path($arquivo);
        
        $this->info("Processando arquivo: $arquivo");
        $this->info("Caminho completo: $caminhoCompleto");
        
        try {
            // Salvar texto extraído para análise
            $textoExtraido = $this->extrairTextoPDF($caminhoCompleto);
            $debugFile = storage_path('app/debug_pdf_text.txt');
            file_put_contents($debugFile, $textoExtraido);
            $this->info("Texto extraído salvo em: " . $debugFile);
            
            if ($debug) {
                $this->info("\n=== PRIMEIRAS 50 LINHAS DO TEXTO EXTRAÍDO ===");
                $linhas = explode("\n", $textoExtraido);
                for ($i = 0; $i < min(50, count($linhas)); $i++) {
                    $this->line("[$i]: " . trim($linhas[$i]));
                }
            }
            
            $dados = $this->extrairTodosOsDadosMelhorado($textoExtraido);
            
            $this->info("\n=== RESULTADOS DA EXTRAÇÃO ===");
            $this->info("Ano: " . ($dados['ano'] ?? 'NÃO ENCONTRADO'));
            $this->info("Localidade: " . ($dados['localidade'] ?? 'NÃO ENCONTRADA'));
            $this->info("Nível médio: " . ($dados['nivel_medio'] ?? 'NÃO ENCONTRADO'));
            $this->info("Total de meses: " . count($dados['dados_estruturados']));
            
            foreach ($dados['dados_estruturados'] as $mes => $dias) {
                $this->info("Mês $mes: " . count($dias) . " dias");
                if ($debug && count($dias) > 0) {
                    $primeirosDias = array_slice($dias, 0, 3, true);
                    foreach ($primeirosDias as $dia => $registros) {
                        $this->info("  - Dia $dia: " . count($registros) . " registros");
                    }
                }
            }

            // Testar datas específicas
            $this->testarDatasEspecificas($dados);

        } catch (\Exception $e) {
            $this->error("Erro ao processar PDF: " . $e->getMessage());
            $this->error("Stack trace: " . $e->getTraceAsString());
        }
    }

    private function extrairTextoPDF($caminhoArquivo)
    {
        try {
            $parser = new Parser();
            $pdf = $parser->parseFile($caminhoArquivo);
            return $pdf->getText();
        } catch (\Exception $e) {
            throw new \Exception('Erro na leitura do PDF: ' . $e->getMessage());
        }
    }

    /**
     * EXTRAÇÃO MELHORADA - Versão mais robusta
     */
    private function extrairTodosOsDadosMelhorado($text)
    {
        $lines = explode("\n", $text);
        
        $dados = [
            'texto_completo' => $text,
            'ano' => null,
            'localidade' => null,
            'nivel_medio' => null,
            'dados_estruturados' => []
        ];

        $meses = [
            'Janeiro' => 1, 'Fevereiro' => 2, 'Março' => 3, 'Abril' => 4,
            'Maio' => 5, 'Junho' => 6, 'Julho' => 7, 'Agosto' => 8,
            'Setembro' => 9, 'Outubro' => 10, 'Novembro' => 11, 'Dezembro' => 12
        ];

        // EXTRAÇÃO DE INFORMAÇÕES GERAIS - MAIS ROBUSTA
        foreach ($lines as $line) {
            $line = trim($line);
            
            // Extrair ano - múltiplos padrões
            if (preg_match('/- (\d{4})$/', $line, $matches)) {
                $dados['ano'] = $matches[1];
                $this->info("[DEBUG] Ano encontrado: " . $dados['ano']);
            }
            
            // Extrair localidade
            if (strpos($line, 'PORTO DE ANGRA DOS REIS') !== false) {
                $dados['localidade'] = trim($line);
                $this->info("[DEBUG] Localidade encontrada: " . $dados['localidade']);
            }
            
            // Extrair nível médio - múltiplos padrões
            if (preg_match('/Nível Médio\s+([\d.]+)\s*m/', $line, $matches)) {
                $dados['nivel_medio'] = floatval($matches[1]);
                $this->info("[DEBUG] Nível médio encontrado: " . $dados['nivel_medio']);
            }
        }

        // EXTRAÇÃO DE DADOS POR MÊS E DIA - ABORDAGEM COMPLETAMENTE REVISADA
        $mesAtual = null;
        $mesNumero = null;
        $processandoDados = false;

        foreach ($lines as $index => $line) {
            $line = trim($line);
            
            // VERIFICAR SE É UM MÊS - abordagem mais flexível
            foreach ($meses as $mesNome => $mesNum) {
                // Verifica se a linha contém APENAS o nome do mês
                if ($line === $mesNome) {
                    $mesAtual = $mesNome;
                    $mesNumero = $mesNum;
                    $dados['dados_estruturados'][$mesNumero] = [];
                    $processandoDados = true;
                    $this->info("[DEBUG] Iniciando mês: $mesNome ($mesNumero)");
                    break;
                }
            }

            if ($processandoDados && $mesNumero) {
                // PADRÃO 1: Linha completa com dia da semana
                // Exemplo: "01 QUA 0344 1.16 1047 0.39 1451 1.10 2246 -0.01"
                if (preg_match('/^(\d{1,2})\s+[A-Z]{3}\s+(\d{4}\s+[-\d.]+\s+\d{4}\s+[-\d.]+\s+\d{4}\s+[-\d.]+\s+\d{4}\s+[-\d.]+)$/', $line, $matches)) {
                    $dia = (int)$matches[1];
                    $dadosDia = $this->extrairHorariosDaLinhaMelhorado($matches[2]);
                    
                    if (!empty($dadosDia)) {
                        $dados['dados_estruturados'][$mesNumero][$dia] = $dadosDia;
                        $this->info("[DEBUG] Dia $dia/$mesNumero processado: " . count($dadosDia) . " registros");
                    }
                }
                // PADRÃO 2: Linha com menos dados
                elseif (preg_match('/^(\d{1,2})\s+[A-Z]{3}\s+(\d{4}\s+[-\d.]+(?:\s+\d{4}\s+[-\d.]+)*)$/', $line, $matches)) {
                    $dia = (int)$matches[1];
                    $dadosDia = $this->extrairHorariosDaLinhaMelhorado($matches[2]);
                    
                    if (!empty($dadosDia)) {
                        $dados['dados_estruturados'][$mesNumero][$dia] = $dadosDia;
                        $this->info("[DEBUG] Dia $dia/$mesNumero processado (padrão 2): " . count($dadosDia) . " registros");
                    }
                }
                // PADRÃO 3: Apenas números (dia sem dia da semana)
                elseif (preg_match('/^(\d{1,2})\s+(\d{4}\s+[-\d.]+(?:\s+\d{4}\s+[-\d.]+)*)$/', $line, $matches)) {
                    $dia = (int)$matches[1];
                    $dadosDia = $this->extrairHorariosDaLinhaMelhorado($matches[2]);
                    
                    if (!empty($dadosDia)) {
                        $dados['dados_estruturados'][$mesNumero][$dia] = $dadosDia;
                        $this->info("[DEBUG] Dia $dia/$mesNumero processado (padrão 3): " . count($dadosDia) . " registros");
                    }
                }
                
                // VERIFICAR SE ENCONTROU O PRÓXIMO MÊS
                if (isset($lines[$index + 1])) {
                    $proximaLinha = trim($lines[$index + 1]);
                    foreach ($meses as $mesNome => $mesNum) {
                        if ($proximaLinha === $mesNome) {
                            $processandoDados = false;
                            $this->info("[DEBUG] Finalizando mês $mesAtual, próximo mês: $mesNome");
                            break 2; // Sai dos dois loops
                        }
                    }
                }
            }
        }

        return $dados;
    }

    /**
     * EXTRAÇÃO DE HORÁRIOS MELHORADA
     */
    private function extrairHorariosDaLinhaMelhorado($linha)
    {
        $dados = [];
        
        // Padrão MELHORADO para capturar TODOS os pares horário-altura
        $pattern = '/(\d{4})\s+([-]?\d+\.\d+)/';
        
        if (preg_match_all($pattern, $linha, $matches)) {
            for ($i = 0; $i < count($matches[1]); $i++) {
                $horario = $matches[1][$i];
                $altura = floatval($matches[2][$i]);
                
                // Formatar horário (0344 → 03:44)
                $horarioFormatado = substr($horario, 0, 2) . ':' . substr($horario, 2, 2);
                
                // Determinar tipo de maré
                $tipo = $this->determinarTipoMare($altura);
                
                $dados[] = [
                    'horario' => $horarioFormatado,
                    'altura' => $altura,
                    'tipo' => $tipo
                ];
            }
            $this->info("[DEBUG] Extraídos " . count($dados) . " horários da linha: $linha");
        } else {
            $this->warn("[DEBUG] Nenhum horário encontrado na linha: $linha");
        }

        return $dados;
    }

    private function determinarTipoMare($altura)
    {
        if ($altura < 0) {
            return 'Baixa';
        }
        
        if ($altura >= 0.8) {
            return 'Alta';
        } elseif ($altura <= 0.3) {
            return 'Baixa';
        }
        
        return $altura >= 0.5 ? 'Alta' : 'Baixa';
    }

    private function testarDatasEspecificas($dados)
    {
        $this->info("\n=== TESTE DE DATAS ESPECÍFICAS ===");
        
        $datasTeste = [
            [3, 7],  // 7 de março
            [3, 8],  // 8 de março
            [3, 9],  // 9 de março
            [1, 1],  // 1 de janeiro
            [12, 31] // 31 de dezembro
        ];

        foreach ($datasTeste as $data) {
            list($mes, $dia) = $data;
            if (isset($dados['dados_estruturados'][$mes][$dia])) {
                $this->info("Dados para $dia/$mes/" . ($dados['ano'] ?? '2025') . ":");
                foreach ($dados['dados_estruturados'][$mes][$dia] as $mare) {
                    $this->info("  {$mare['horario']} - {$mare['altura']}m - {$mare['tipo']}");
                }
            } else {
                $this->warn("Dados para $dia/$mes/" . ($dados['ano'] ?? '2025') . " NÃO encontrados");
            }
        }
    }
}