<?php
namespace App\Http\Controllers\Gestao;

use App\Http\Controllers\Controller;
use App\Models\ContestDate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;

class GestaoContestController extends Controller
{
    // ── Lista todos os contests ───────────────────────────────────────────────
    public function index()
    {
        $contests    = ContestDate::orderByDesc('id')->get();
        $autoAtivar  = config('contest.auto_ativar', false);

        $etapasPorContest = DB::table('contest_etapas')
            ->selectRaw('contest_id, COUNT(*) as total, SUM(status="concluida") as concluidas')
            ->groupBy('contest_id')
            ->get()->keyBy('contest_id');

        return view('gestao.contests',
            compact('contests', 'autoAtivar', 'etapasPorContest'));
    }

    // ── Ativar contest (flag → 1) ─────────────────────────────────────────────
    public function ativar(Request $request, int $id)
    {
        $contest = ContestDate::findOrFail($id);

        if ($contest->flag === ContestDate::FLAG_ARQUIVADO) {
            return back()->with('erro', 'Contest arquivado. Os dados foram removidos. Impossível ativar.');
        }

        DB::transaction(function () use ($contest) {
            // Suspender o ativo atual (→ Encerrado)
            ContestDate::where('flag', ContestDate::FLAG_ATIVO)
                ->where('id', '!=', $contest->id)
                ->update(['flag' => ContestDate::FLAG_ENCERRADO]);

            $contest->update(['flag' => ContestDate::FLAG_ATIVO]);

            // Garantir que existem etapas para este contest
            $existentes = DB::table('contest_etapas')
                ->where('contest_id', $contest->id)->pluck('etapa')->toArray();

            $etapasNomes = [
                'A'=>'Importar LOGs','1'=>'Juntar LOGs','2'=>'Validar QSOs',
                '3'=>'Validar Tempo/Banda','4'=>'Claimed Score','5'=>'Validar Contatos',
                '6'=>'Sem LOGs / DUPs','7'=>'Pontos+Multi+FS','8'=>'Final Score',
                '9'=>'Resultado Final','10'=>'Records','11'=>'Encerrar Contest',
            ];
            foreach ($etapasNomes as $e => $n) {
                if (!in_array($e, $existentes)) {
                    DB::table('contest_etapas')->insert([
                        'etapa'=>$e,'nome'=>$n,'contest_id'=>$contest->id,
                        'status'=>'pendente','segundos_gastos'=>0,
                    ]);
                }
            }
        });

        activity()->causedBy(auth()->user())
            ->log("Contest #{$id} ativado manualmente.");

        return back()->with('sucesso', "Contest #{$id} ({$contest->name} {$contest->start_date->format('Y')}) ativado.");
    }

    // ── Arquivar contest encerrado (flag → 3) ─────────────────────────────────
    public function arquivar(Request $request, int $id)
    {
        $request->validate(
            ['confirmacao' => 'required|in:ARQUIVAR'],
            ['confirmacao.in' => 'Digite exatamente ARQUIVAR (maiúsculas) para confirmar.']
        );

        $contest = ContestDate::findOrFail($id);

        if ($contest->flag === ContestDate::FLAG_ATIVO) {
            return back()->with('erro', 'Não é possível arquivar o contest ativo. Execute a Etapa 11 primeiro.');
        }
        if ($contest->flag === ContestDate::FLAG_FUTURO) {
            return back()->with('erro', 'Não é possível arquivar um contest Futuro. Exclua-o se necessário.');
        }
        if ($contest->flag === ContestDate::FLAG_ARQUIVADO) {
            return back()->with('erro', 'Contest já está arquivado.');
        }

        $backupDir = storage_path("app/backup/contest_{$id}_" . date('Ymd_His'));
        @mkdir($backupDir, 0755, true);

        DB::transaction(function () use ($contest, $backupDir, $id) {
            // Exportar dados para CSV
            foreach (['qsos_result','logs_cabecalhos','logs_qsos','resultados_final','staging_scores'] as $tabela) {
                try {
                    $rows = DB::table($tabela)->where('contest_id', $id)->get();
                    if ($rows->isEmpty()) continue;
                    $fp = fopen("{$backupDir}/{$tabela}.csv", 'w');
                    fputcsv($fp, array_keys((array)$rows->first()));
                    foreach ($rows as $row) { fputcsv($fp, (array)$row); }
                    fclose($fp);
                    DB::table($tabela)->where('contest_id', $id)->delete();
                } catch (\Throwable) {}
            }
            // Remover etapas
            DB::table('contest_etapas')->where('contest_id', $id)->delete();
            // Marcar como arquivado
            $contest->update(['flag' => ContestDate::FLAG_ARQUIVADO]);
        });

        // Backup LOGs físicos do ano correspondente ao contest
        $anoContest = \Carbon\Carbon::parse($contest->start_date)->year;
        $logsDir    = config('contest.logs_base_dir') . DIRECTORY_SEPARATOR . $anoContest;
        $backupLogs = "{$backupDir}/logs";
        if (is_dir($logsDir)) {
            @mkdir($backupLogs, 0755, true);
            foreach (glob($logsDir . DIRECTORY_SEPARATOR . '*.log') ?: [] as $f) {
                @copy($f, $backupLogs . DIRECTORY_SEPARATOR . basename($f));
            }
        }

        activity()->causedBy(auth()->user())
            ->log("Contest #{$id} arquivado. Backup em: {$backupDir}");

        return back()->with('sucesso', "Contest #{$id} arquivado. Backup salvo em: storage/app/backup/");
    }

    // ── Criar próximo contest ─────────────────────────────────────────────────
    public function criarProximo()
    {
        $ultimo  = ContestDate::orderByDesc('id')->first();
        $anoBase = $ultimo
            ? (int)\Carbon\Carbon::parse($ultimo->start_date)->format('Y') + 1
            : (int)date('Y') + 1;

        // 3º sábado de julho
        $data = \Carbon\Carbon::create($anoBase, 7, 1)->startOfDay();
        while ($data->dayOfWeek !== 6) { $data->addDay(); }
        $data->addDays(14);

        $proximo = [
            'name'        => 'LABRE-DX',
            'start_date'  => $data->copy()->format('Y-m-d\TH:i'),
            'end_date'    => $data->copy()->addDay()->format('Y-m-d\T') . '23:59',
            'limit_young' => $data->copy()->subYears(25)->subDay()->toDateString(),
            'inicio_log'  => $data->toDateString(),
            'limit_log'   => $data->copy()->addDays(5)->toDateString(),
        ];

        return view('gestao.criar-contest', compact('proximo', 'anoBase'));
    }

    public function storeProximo(Request $request)
    {
        $dados = $request->validate([
            'name'        => 'required|string|max:20',
            'start_date'  => 'required|date',
            'end_date'    => 'required|date|after:start_date',
            'limit_young' => 'required|date',
            'inicio_log'  => 'required|date',
            'limit_log'   => 'required|date|after:inicio_log',
        ]);
        $dados['flag'] = ContestDate::FLAG_FUTURO;

        $novoId = DB::table('contest_date')->insertGetId($dados);

        activity()->causedBy(auth()->user())
            ->log("Contest #{$novoId} criado para {$dados['start_date']}.");

        return redirect()->route('gestao.contests.index')
            ->with('sucesso', "Contest #{$novoId} criado como Futuro (flag=0).");
    }

    // ── Toggle ativação automática ────────────────────────────────────────────
    public function toggleAutoAtivar()
    {
        $atual  = config('contest.auto_ativar', false);
        $novo   = !$atual;
        $novoStr= $novo ? 'true' : 'false';

        $envPath    = base_path('.env');
        $envContent = file_get_contents($envPath);

        if (str_contains($envContent, 'AUTO_ATIVAR_CONTEST=')) {
            $envContent = preg_replace('/AUTO_ATIVAR_CONTEST=\S*/', "AUTO_ATIVAR_CONTEST={$novoStr}", $envContent);
        } else {
            $envContent .= "\nAUTO_ATIVAR_CONTEST={$novoStr}\n";
        }
        file_put_contents($envPath, $envContent);
        Artisan::call('config:clear');

        $msg = $novo
            ? '✅ Ativação automática LIGADA. Configure o Task Scheduler para rodar: php artisan schedule:run'
            : '⛔ Ativação automática DESLIGADA.';

        return back()->with('sucesso', $msg);
    }

    // ── Reprocessar contest encerrado ─────────────────────────────────────────
    public function reprocessar(Request $request, int $id)
    {
        $request->validate(
            ['confirmacao' => 'required|in:REPROCESSAR'],
            ['confirmacao.in' => 'Digite exatamente REPROCESSAR (maiúsculas) para confirmar.']
        );

        $contest = ContestDate::findOrFail($id);

        if ($contest->flag === ContestDate::FLAG_ATIVO) {
            return back()->with('erro', 'Este contest já está ativo.');
        }
        if ($contest->flag === ContestDate::FLAG_ARQUIVADO) {
            return back()->with('erro', 'Contest arquivado — dados removidos. Restaure o backup antes de reprocessar.');
        }

        DB::transaction(function () use ($contest, $id) {
            // Suspender o ativo atual
            ContestDate::where('flag', ContestDate::FLAG_ATIVO)
                ->where('id', '!=', $id)
                ->update(['flag' => ContestDate::FLAG_ENCERRADO]);

            // Ativar este contest
            $contest->update(['flag' => ContestDate::FLAG_ATIVO]);

            // Resetar etapas
            DB::table('contest_etapas')
                ->where('contest_id', $id)
                ->update([
                    'status'=>'pendente','executada_em'=>null,'executada_por'=>null,
                    'total_processados'=>0,'total_validos'=>0,'total_invalidos'=>0,
                    'tempo_gasto'=>null,'segundos_gastos'=>0,
                ]);
        });

        activity()->causedBy(auth()->user())
            ->log("Contest #{$id} reativado para reprocessamento.");

        return redirect()->route('dashboard')
            ->with('sucesso', "Contest #{$id} reativado. Etapas resetadas. Inicie pelo Dashboard.");
    }
}
