<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\ProjetosProgramas\ProjetoPrograma;
use App\Models\ProjetosProgramas\Ods;
use App\Models\Structure;
use App\Services\LegacyDataMapper;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

/**
 * @deprecated Esta seeder foi consolidada em ProjetosProgramasMigrationSeeder.
 * Use: php artisan db:seed --class=ProjetosProgramasMigrationSeeder
 *
 * Esta seeder ainda existe para referência, mas não deve ser executada diretamente.
 * A seeder consolidada inclui esta funcionalidade e muito mais, além de incorporar
 * a lógica do LegacyDataMapper diretamente na classe.
 */
class LegacyProjetosMigrationSeeder extends Seeder
{
    private array $orgaoMap = [];
    private array $stats = [
        'total' => 0,
        'migrated' => 0,
        'skipped' => 0,
        'errors' => 0,
    ];

    public function run(): void
    {
        $this->command->info('===========================================');
        $this->command->info('Iniciando migração de projetos legados...');
        $this->command->info('===========================================');

        // Load orgao mapping from cache
        $this->orgaoMap = cache()->get('legacy_orgao_map', []);

        if (empty($this->orgaoMap)) {
            $this->command->warn('Mapa de órgãos não encontrado. Execute LegacyProjetosOrgaosSeeder primeiro.');
        }

        // Step 1: Clean existing test data
        $this->cleanExistingData();

        // Step 2: Migrate projects
        $this->migrateProjects();

        // Step 3: Show statistics
        $this->showStatistics();
    }

    private function cleanExistingData(): void
    {
        $this->command->info('');
        $this->command->info('Limpando dados de teste existentes...');

        DB::beginTransaction();
        try {
            // Delete relationships first
            DB::table('project_program_ods')->delete();
            DB::table('project_program_orgaos')->delete();

            // Delete attachments
            $attachmentCount = DB::table('project_program_attachments')->count();
            DB::table('project_program_attachments')->delete();

            // Delete projects
            $projectCount = DB::table('projects_programs')->count();
            DB::table('projects_programs')->delete();

            DB::commit();

            $this->command->info("✓ Removidos {$projectCount} projetos");
            $this->command->info("✓ Removidos {$attachmentCount} anexos");
            $this->command->info("✓ Relacionamentos limpos");
        } catch (\Exception $e) {
            DB::rollBack();
            $this->command->error("Erro ao limpar dados: " . $e->getMessage());
            throw $e;
        }
    }

    private function migrateProjects(): void
    {
        $this->command->info('');
        $this->command->info('Migrando projetos do CSV...');

        $csvPath = base_path('Projetos.csv');

        if (!file_exists($csvPath)) {
            $this->command->error("Arquivo não encontrado: {$csvPath}");
            return;
        }

        $handle = fopen($csvPath, 'r');
        if (!$handle) {
            $this->command->error("Não foi possível abrir o arquivo: {$csvPath}");
            return;
        }

        // Read header
        $header = fgetcsv($handle);
        if (!$header) {
            $this->command->error("Arquivo CSV vazio ou inválido");
            fclose($handle);
            return;
        }

        // Remove BOM if present
        $header[0] = preg_replace('/^\x{FEFF}/u', '', $header[0]);

        $lineNumber = 1;
        $progressBar = $this->command->getOutput()->createProgressBar();
        $progressBar->start();

        while (($row = fgetcsv($handle)) !== false) {
            $lineNumber++;
            $this->stats['total']++;

            if (count($row) < count($header)) {
                $this->stats['skipped']++;
                $progressBar->advance();
                continue;
            }

            $data = array_combine($header, $row);

            try {
                $this->migrateProject($data);
                $this->stats['migrated']++;
            } catch (\Exception $e) {
                $this->stats['errors']++;
                $this->command->error("\nErro na linha {$lineNumber}: " . $e->getMessage());
            }

            $progressBar->advance();
        }

        $progressBar->finish();
        $this->command->info('');
        fclose($handle);
    }

    private function migrateProject(array $data): void
    {
        DB::beginTransaction();
        try {
            // Map gestor (órgão)
            $gestorId = null;
            if (!empty($data['pro_dimen_orgao'])) {
                $gestorId = $this->orgaoMap[$data['pro_dimen_orgao']] ?? null;
            }

            // If no gestor found, try to find a default structure
            if (!$gestorId) {
                $defaultStructure = Structure::where('abbreviation', 'PMAR')->first();
                $gestorId = $defaultStructure?->id;
            }

            // Parse dates
            $dataInicio = LegacyDataMapper::parseDate($data['pro_crono_inicio']);
            if (!$dataInicio) {
                $dataInicio = '2022-01-01'; // Default date
            }

            $dataTermino = LegacyDataMapper::parseDate($data['pro_crono_fim']);

            // Build observacoes with extra fields
            $observacoes = LegacyDataMapper::cleanText($data['pro_dados_obs'] ?? '');
            $extraInfo = [];

            if (!empty($data['pro_dados_status_outro'])) {
                $extraInfo[] = "Status: " . $data['pro_dados_status_outro'];
            }
            if (!empty($data['pro_dados_dificuldades_outro'])) {
                $extraInfo[] = "Dificuldades: " . $data['pro_dados_dificuldades_outro'];
            }

            if (!empty($extraInfo)) {
                $observacoes = trim(($observacoes ? $observacoes . "\n\n" : '') . implode("\n", $extraInfo));
            }

            // Build relacao_ppa with extra fields
            $relacaoPpa = LegacyDataMapper::cleanText($data['pro_dimen_acao'] ?? '');
            if (!empty($data['pro_inves_horizonte'])) {
                $relacaoPpa = trim(($relacaoPpa ? $relacaoPpa . "\n" : '') . "Horizonte: " . $data['pro_inves_horizonte']);
            }
            if (!empty($data['pro_inves_relacao'])) {
                $relacaoPpa = trim(($relacaoPpa ? $relacaoPpa . "\n" : '') . "Relação: " . $data['pro_inves_relacao']);
            }

            // Create project
            $project = ProjetoPrograma::create([
                'denominacao' => LegacyDataMapper::cleanText($data['pro_dimen_denominacao']) ?? 'Sem denominação',
                'num_processo_adm' => LegacyDataMapper::cleanText($data['pro_dimen_numprocessoadm']),
                'gestor_structure_id' => $gestorId,
                'tipo_id' => LegacyDataMapper::mapTipo($data['pro_dimen_tipo']),
                'programa_ppa' => LegacyDataMapper::cleanText($data['pro_dimen_programa']),
                'endereco' => LegacyDataMapper::cleanText($data['pro_dimen_endereco']),
                'bairro' => LegacyDataMapper::cleanText($data['pro_dimen_bairro']),
                'data_inicio' => $dataInicio,
                'data_termino' => $dataTermino,
                'prazo_id' => LegacyDataMapper::mapPrazo($data['pro_crono_prazo_entrega']),
                'codigo' => LegacyDataMapper::cleanText($data['pro_dimen_codigo']),
                'acompanhamento_governo' => LegacyDataMapper::parseBoolean($data['pro_dimen_acompanhamento'] ?? 0),
                'classificacao_id' => LegacyDataMapper::mapClassificacao($data['pro_dimen_classificacao']),
                'etapa_id' => LegacyDataMapper::mapEtapa($data['pro_dimen_etapa']),
                'relacao_ppa' => $relacaoPpa,
                'eixo_id' => $this->mapEixo($data['pro_eixo'] ?? ''),
                'area_id' => $this->mapArea($data['pro_area'] ?? ''),
                'contato_nome' => LegacyDataMapper::cleanText($data['pro_contato_nome']),
                'contato_matricula' => LegacyDataMapper::cleanText($data['pro_contato_matricula']),
                'contato_ramal' => LegacyDataMapper::cleanText($data['pro_contato_ramal']),
                'contato_telefone' => LegacyDataMapper::cleanText($data['pro_contato_telefone']),
                'contato_email' => LegacyDataMapper::cleanText($data['pro_contato_email']),
                'descricao_objeto' => LegacyDataMapper::cleanText($data['pro_dados_objeto']),
                'justificativa' => LegacyDataMapper::cleanText($data['pro_dados_justificativa']),
                'descricao_responsabilidades' => LegacyDataMapper::cleanText($data['pro_dados_responsabilidades']),
                'status_id' => LegacyDataMapper::mapStatus($data['pro_dados_status']),
                'dificuldade_id' => LegacyDataMapper::mapDificuldade($data['pro_dados_dificuldades']),
                'gargalos' => LegacyDataMapper::cleanText($data['pro_dados_gargalos']),
                'observacoes' => $observacoes,
                'fonte_id' => LegacyDataMapper::mapFonte($data['pro_inves_fonte']),
                'fonte_outro' => LegacyDataMapper::cleanText($data['pro_inves_fonte_outro']),
                'custo_total' => LegacyDataMapper::parseDecimal($data['pro_inves_custototal']) ?? 0,
                'custeio_anual' => LegacyDataMapper::parseDecimal($data['pro_inves_custoanual']) ?? 0,
                'ppa_2022' => LegacyDataMapper::parseDecimal($data['pro_inves_previsto1']) ?? 0,
                'ppa_2023' => LegacyDataMapper::parseDecimal($data['pro_inves_previsto2']) ?? 0,
                'ppa_2024' => LegacyDataMapper::parseDecimal($data['pro_inves_previsto3']) ?? 0,
                'ppa_2025' => LegacyDataMapper::parseDecimal($data['pro_inves_previsto4']) ?? 0,
                'loa_2022' => LegacyDataMapper::parseDecimal($data['pro_inves_loa1']) ?? 0,
                'loa_2023' => LegacyDataMapper::parseDecimal($data['pro_inves_loa2']) ?? 0,
                'loa_2024' => LegacyDataMapper::parseDecimal($data['pro_inves_loa3']) ?? 0,
                'loa_2025' => LegacyDataMapper::parseDecimal($data['pro_inves_loa4']) ?? 0,
                'manutencao_2022' => LegacyDataMapper::parseDecimal($data['pro_inves_manutencao1']) ?? 0,
                'manutencao_2023' => LegacyDataMapper::parseDecimal($data['pro_inves_manutencao2']) ?? 0,
                'manutencao_2024' => LegacyDataMapper::parseDecimal($data['pro_inves_manutencao3']) ?? 0,
                'manutencao_2025' => LegacyDataMapper::parseDecimal($data['pro_inves_manutencao4']) ?? 0,
                'conve_orgao' => LegacyDataMapper::cleanText($data['pro_conve_orgao']),
                'conve_orgao_outro' => LegacyDataMapper::cleanText($data['pro_conve_orgao_outro']),
                'conve_proposta' => LegacyDataMapper::cleanText($data['pro_conve_proposta']),
                'conve_convenio' => LegacyDataMapper::cleanText($data['pro_conve_convenio']),
                'status_registro' => 'COMPLETO',
                'identificacao_done' => true,
                'cronograma_done' => true,
                'areas_done' => true,
                'contato_done' => true,
                'dados_done' => true,
                'investimento_done' => true,
            ]);

            // Attach ODS
            $odsIds = LegacyDataMapper::parseOdsColumns($data);
            if (!empty($odsIds)) {
                $odsRecords = Ods::whereIn('codigo', array_map(function ($id) {
                    return str_pad($id, 2, '0', STR_PAD_LEFT);
                }, $odsIds))->pluck('id')->toArray();

                if (!empty($odsRecords)) {
                    $project->ods()->attach($odsRecords);
                }
            }

            // Attach orgaos envolvidos
            $orgaosEnvolvidosIds = LegacyDataMapper::parseCommaSeparatedIds($data['pro_dados_orgaos_envolvidos'] ?? '');
            $structureIds = [];
            foreach ($orgaosEnvolvidosIds as $orgaoId) {
                if (isset($this->orgaoMap[$orgaoId])) {
                    $structureIds[] = $this->orgaoMap[$orgaoId];
                }
            }

            if (!empty($structureIds)) {
                $project->orgaosEnvolvidos()->attach($structureIds);
            }

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }
    }

    private function mapEixo(?string $eixoName): ?int
    {
        if (empty($eixoName)) {
            return null;
        }

        $eixos = [
            'Gestão pública eficiente' => 1,
            'Angra, cidade com desenvolvimento e oportunidade' => 2,
            'Angra, cidade acolhedora e saudável' => 3,
            'Angra, cidade moderna e do conhecimento' => 4,
            'Angra, cidade sustentável' => 5,
            'Angra, cidade pacífica e segura' => 6,
        ];

        // Try exact match
        if (isset($eixos[$eixoName])) {
            return $eixos[$eixoName];
        }

        // Try to find by number
        if (is_numeric($eixoName)) {
            $num = (int) $eixoName;
            if ($num >= 1 && $num <= 6) {
                return $num;
            }
        }

        return null;
    }

    private function mapArea(?string $areaName): ?int
    {
        if (empty($areaName)) {
            return null;
        }

        // This is a simplified mapping - you may need to adjust based on actual data
        $areas = DB::table('project_program_areas')->get();

        foreach ($areas as $area) {
            if (stripos($area->nome, $areaName) !== false || stripos($areaName, $area->nome) !== false) {
                return $area->id;
            }
        }

        return null;
    }

    private function showStatistics(): void
    {
        $this->command->info('');
        $this->command->info('===========================================');
        $this->command->info('Estatísticas da Migração');
        $this->command->info('===========================================');
        $this->command->info("Total de linhas processadas: {$this->stats['total']}");
        $this->command->info("Projetos migrados: {$this->stats['migrated']}");
        $this->command->info("Linhas ignoradas: {$this->stats['skipped']}");
        $this->command->info("Erros: {$this->stats['errors']}");
        $this->command->info('===========================================');
    }
}
