<?php

namespace App\Http\Controllers\Public;

use App\Http\Controllers\Controller;
use App\Models\Submission;
use App\Services\SubmissionService;
use App\Services\TurnstileService;
use App\Mail\SubmissionConfirmation;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\RateLimiter;

class SubmissionController extends Controller
{
    public function showForm(Request $request, string $type)
    {
        if (!in_array($type, ['update', 'new'])) {
            abort(404);
        }

        return view('public.form', [
            'type' => $type,
            'estados_civis' => Submission::ESTADOS_CIVIS,
            'habilitacoes' => Submission::HABILITACOES,
            'turnstile_key' => config('services.turnstile.site_key'),
        ]);
    }

    public function submit(Request $request, string $type)
    {
        if (!in_array($type, ['update', 'new'])) {
            abort(404);
        }

        // Rate limiting
        $ip = $request->ip();
        $limiterKey = 'submission:' . $ip;
        $maxAttempts = (int) env('SUBMISSION_RATE_LIMIT', 5);
        $decayMinutes = (int) env('SUBMISSION_RATE_LIMIT_MINUTES', 60);

        if (RateLimiter::tooManyAttempts($limiterKey, $maxAttempts)) {
            return back()->withErrors(['rate_limit' => 'Demasiadas submissões. Tente novamente mais tarde.'])->withInput();
        }
        RateLimiter::hit($limiterKey, $decayMinutes * 60);

        // Turnstile validation
        if (!TurnstileService::verify($request->input('cf-turnstile-response'))) {
            return back()->withErrors(['captcha' => 'Verificação de segurança falhou. Tente novamente.'])->withInput();
        }

        // Form validation
        $rules = [
            'nome_completo' => 'required|string|max:255',
            'nif' => 'required|string|min:9|max:9|regex:/^\d{9}$/',
            'data_nascimento' => 'required|date|before:today',
            'email' => 'required|email|max:255',
            'telemovel' => 'required|string|max:20',
            'contacto_emergencia_nome' => 'required|string|max:255',
            'contacto_emergencia_relacao' => 'required|string|max:100',
            'contacto_emergencia_telefone' => 'required|string|max:20',
            'morada_original' => 'required|string|max:500',
            'estado_civil' => 'required|in:' . implode(',', array_keys(Submission::ESTADOS_CIVIS)),
            'nr_dependentes' => 'required|integer|min:0|max:20',
            'habilitacoes_literarias' => 'required|in:' . implode(',', array_keys(Submission::HABILITACOES)),
            'declaracao_verdade' => 'required|accepted',
        ];

        // Mudou morada e comprovativo apenas para atualizações
        if ($type === 'update') {
            $rules['mudou_morada'] = 'required|in:0,1';

            if ($request->input('mudou_morada') === '1') {
                $rules['comprovativo'] = 'required|file|mimes:pdf,jpg,jpeg,png|max:8192';
            }
        }

        $messages = [
            'nif.regex' => 'O NIF deve conter exatamente 9 dígitos.',
            'declaracao_verdade.accepted' => 'Deve confirmar que os dados são verdadeiros e atuais.',
            'comprovativo.required' => 'O comprovativo de morada é obrigatório quando indica mudança de morada.',
            'comprovativo.max' => 'O ficheiro não pode exceder 8 MB.',
            'comprovativo.mimes' => 'O ficheiro deve ser PDF, JPG ou PNG.',
        ];

        $validated = $request->validate($rules, $messages);

        $file = $request->file('comprovativo');

        $submission = SubmissionService::process($validated, $type, $file);

        // Enviar email de confirmação
        try {
            Mail::to($validated['email'])->send(new SubmissionConfirmation($submission));
        } catch (\Exception $e) {
            \Log::warning('Failed to send submission confirmation email: ' . $e->getMessage());
        }

        return redirect()->route('submission.success', ['id' => $submission->id])
            ->with('submission_id', $submission->id);
    }

    public function success(Request $request)
    {
        $submissionId = $request->session()->get('submission_id') ?? $request->query('id');

        return view('public.success', [
            'submission_id' => $submissionId,
        ]);
    }
}
