<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\AuditLog;
use App\Models\Submission;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class SyncController extends Controller
{
    /**
     * Retorna submissions nao sincronizadas (dados decriptados via Eloquent).
     */
    public function getUnsynced(): JsonResponse
    {
        $submissions = Submission::whereNull('synced_at')
            ->orderBy('created_at', 'asc')
            ->get();

        return response()->json([
            'success' => true,
            'count' => $submissions->count(),
            'submissions' => $submissions->map(fn (Submission $s) => [
                'id' => $s->id,
                'type' => $s->type,
                'nome_completo' => $s->nome_completo,
                'nif' => $s->nif,
                'data_nascimento' => $s->data_nascimento?->format('Y-m-d'),
                'email' => $s->email,
                'telemovel' => $s->telemovel,
                'contacto_emergencia_nome' => $s->contacto_emergencia_nome,
                'contacto_emergencia_relacao' => $s->contacto_emergencia_relacao,
                'contacto_emergencia_telefone' => $s->contacto_emergencia_telefone,
                'morada_original' => $s->morada_original,
                'morada_corrigida' => $s->morada_corrigida,
                'mudou_morada' => $s->mudou_morada,
                'estado_civil' => $s->estado_civil,
                'nr_dependentes' => $s->nr_dependentes,
                'habilitacoes_literarias' => $s->habilitacoes_literarias,
                'comprovativo_path' => $s->comprovativo_path,
                'comprovativo_original_name' => $s->comprovativo_original_name,
                'status' => $s->status,
                'flag_sem_correspondencia' => $s->flag_sem_correspondencia,
                'flag_ip_fora_pt' => $s->flag_ip_fora_pt,
                'flag_suspeito' => $s->flag_suspeito,
                'diff_data' => $s->diff_data,
                'created_at' => $s->created_at?->toIso8601String(),
                'updated_at' => $s->updated_at?->toIso8601String(),
            ])->values(),
        ]);
    }

    /**
     * Marca submissions como sincronizadas.
     */
    public function markSynced(Request $request): JsonResponse
    {
        $request->validate([
            'ids' => 'required|array',
            'ids.*' => 'integer|exists:submissions,id',
        ]);

        $count = Submission::whereIn('id', $request->ids)
            ->whereNull('synced_at')
            ->update(['synced_at' => now()]);

        return response()->json([
            'success' => true,
            'synced' => $count,
        ]);
    }

    /**
     * Retorna submissions elegiveis para purge (concluidas + synced > 24h).
     */
    public function getPurgeCandidates(): JsonResponse
    {
        $candidates = Submission::where('status', 'concluido')
            ->whereNotNull('synced_at')
            ->where('synced_at', '<', now()->subHours(24))
            ->get(['id', 'comprovativo_path']);

        return response()->json([
            'success' => true,
            'count' => $candidates->count(),
            'candidates' => $candidates->map(fn ($s) => [
                'id' => $s->id,
                'comprovativo_path' => $s->comprovativo_path,
            ])->values(),
        ]);
    }

    /**
     * Lookup de submission por NIF + data de nascimento (para auto-preenchimento no ERP).
     */
    public function lookupByNif(Request $request): JsonResponse
    {
        $request->validate([
            'nif' => 'required|string|size:9',
            'data_nascimento' => 'required|date_format:Y-m-d',
        ]);

        $nifHash = hash('sha256', $request->nif);

        $submission = Submission::where('nif_hash', $nifHash)
            ->where('is_latest', true)
            ->orderByDesc('id')
            ->first();

        if (!$submission) {
            return response()->json([
                'success' => false,
                'error_type' => 'not_found',
                'message' => 'Nenhuma correspondência encontrada.',
            ]);
        }

        if ($submission->data_nascimento?->format('Y-m-d') !== $request->data_nascimento) {
            return response()->json([
                'success' => false,
                'error_type' => 'date_mismatch',
                'message' => 'NIF encontrado mas a Data de Nascimento não corresponde.',
            ]);
        }

        return response()->json([
            'success' => true,
            'data' => [
                'id' => $submission->id,
                'email' => $submission->email,
                'telemovel' => $submission->telemovel,
                'contacto_emergencia_nome' => $submission->contacto_emergencia_nome,
                'contacto_emergencia_relacao' => $submission->contacto_emergencia_relacao,
                'contacto_emergencia_telefone' => $submission->contacto_emergencia_telefone,
                'estado_civil' => $submission->estado_civil,
                'nr_dependentes' => $submission->nr_dependentes,
                'habilitacoes_literarias' => $submission->habilitacoes_label,
            ],
        ]);
    }

    /**
     * Marca uma submission como concluida (chamado pelo ERP apos processar funcionario).
     */
    public function markConcluded(Request $request): JsonResponse
    {
        $request->validate([
            'id' => 'required|integer|exists:submissions,id',
            'mec' => 'nullable|string',
            'nif' => 'nullable|string',
        ]);

        $submission = Submission::findOrFail($request->id);
        $submission->update(['status' => 'concluido']);

        $mec = $request->mec ?? 'N/A';
        $nif = $request->nif ?? 'N/A';

        AuditLog::log(
            'erp_concluded',
            null,
            'submission',
            $submission->id,
            null,
            null,
            "Sabichão puxou dados automaticamente (MEC: {$mec}, NIF: {$nif}). Estado alterado para concluído."
        );

        return response()->json(['success' => true]);
    }

    /**
     * Executa purge de submissions: apaga ficheiros do R2, cria audit log, hard-delete.
     */
    public function executePurge(Request $request): JsonResponse
    {
        $request->validate([
            'ids' => 'required|array',
            'ids.*' => 'integer|exists:submissions,id',
        ]);

        $purged = 0;
        $errors = [];

        foreach ($request->ids as $id) {
            $submission = Submission::where('id', $id)
                ->where('status', 'concluido')
                ->whereNotNull('synced_at')
                ->first();

            if (!$submission) {
                $errors[] = "Submissao #{$id} nao encontrada ou nao elegivel.";
                continue;
            }

            $this->deleteSubmission($submission, 'sync_purge', "Purge automatico: submissao #{$id} apagada apos sync confirmado.");
            $purged++;
        }

        return response()->json([
            'success' => true,
            'purged' => $purged,
            'errors' => $errors,
        ]);
    }

    /**
     * Purge total: apaga TODAS as submissions ja sincronizadas (independente de status/tempo).
     */
    public function purgeAll(): JsonResponse
    {
        $submissions = Submission::whereNotNull('synced_at')->get();

        $purged = 0;
        $errors = [];

        foreach ($submissions as $submission) {
            try {
                $this->deleteSubmission($submission, 'purge_all', "Purge total: submissao #{$submission->id} apagada.");
                $purged++;
            } catch (\Exception $e) {
                $errors[] = "Erro ao apagar #{$submission->id}: {$e->getMessage()}";
            }
        }

        return response()->json([
            'success' => true,
            'purged' => $purged,
            'errors' => $errors,
        ]);
    }

    /**
     * Apaga submissions especificas (spam, testes, etc.) — independente de estado ou sync.
     */
    public function deleteSubmissions(Request $request): JsonResponse
    {
        $request->validate([
            'ids' => 'required|array',
            'ids.*' => 'integer|exists:submissions,id',
            'reason' => 'nullable|string|max:255',
        ]);

        $reason = $request->reason ?? 'Removida manualmente via ERP';
        $deleted = 0;
        $errors = [];

        foreach ($request->ids as $id) {
            $submission = Submission::find($id);
            if (!$submission) {
                $errors[] = "Submissao #{$id} nao encontrada.";
                continue;
            }

            try {
                $this->deleteSubmission($submission, 'manual_delete', "Submissao #{$id} removida: {$reason}");
                $deleted++;
            } catch (\Exception $e) {
                $errors[] = "Erro ao apagar #{$id}: {$e->getMessage()}";
            }
        }

        return response()->json([
            'success' => true,
            'deleted' => $deleted,
            'errors' => $errors,
        ]);
    }

    /**
     * Helper: apaga uma submission (R2 + audit log + hard-delete).
     */
    private function deleteSubmission(Submission $submission, string $action, string $reason): void
    {
        if ($submission->comprovativo_path) {
            try {
                Storage::disk('r2')->delete($submission->comprovativo_path);
            } catch (\Exception $e) {
                // Log mas nao bloqueia
            }
        }

        AuditLog::log($action, null, 'submission', $submission->id, null, null, $reason);

        $submission->delete();
    }
}
