<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Models\AcademicInfo;
use App\Models\Admission;
use App\Models\Attachment;
use App\Models\Dependent;
use Core\Controller;
use Core\Csrf;
use Core\Session;
use Core\Upload;
use Core\Validator;

final class AdmissionController extends Controller
{
    public function create(): void
    {
        $config = require dirname(__DIR__, 2) . '/config/app.php';
        $this->view('admissions/create', [
            'config' => $config,
            'errors' => Session::errors(),
            'error' => Session::getFlash('error'),
        ]);
    }

    public function store(): void
    {
        if (!Csrf::verify($_POST['_token'] ?? null)) {
            http_response_code(419);
            exit('Token CSRF inválido.');
        }

        $errors = Validator::admission($_POST, $_FILES, false);
        $allowedMimeTypes = ['image/jpeg', 'image/png', 'application/pdf'];

        foreach (['profile_photo', 'rg_front', 'rg_back', 'cref_document', 'mei_certificate', 'marriage_certificate', 'divorce_annotation', 'work_card'] as $field) {
            if (isset($_FILES[$field]) && ($_FILES[$field]['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_NO_FILE) {
                $fileError = Validator::file($_FILES[$field], $allowedMimeTypes, 5);
                if ($fileError) $errors[$field] = $fileError;
            }
        }

        if ((int) ($_POST['has_dependents'] ?? 0) === 1 && isset($_FILES['dependent_birth_certificates'])) {
            foreach (array_keys($_POST['dependents'] ?? []) as $index) {
                $file = $this->extractNestedUpload($_FILES['dependent_birth_certificates'], (int) $index);
                if ($file && (int) ($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_NO_FILE) {
                    $fileError = Validator::file($file, $allowedMimeTypes, 5);
                    if ($fileError) {
                        $errors["dependent_birth_certificates.$index"] = $fileError;
                    }
                }
            }
        }

        if (!empty($errors)) {
            Session::flash('error', 'Revise o formulário. Existem campos obrigatórios ou inválidos.');
            Session::putErrors($errors);
            Session::putOldInput($_POST);
            $this->redirectTo('');
        }

        $cpf = preg_replace('/\D/', '', (string)($_POST['cpf'] ?? ''));

        if (Admission::existsByCpf($cpf)) {
            $errors['cpf'] = 'Já existe uma ficha cadastrada com este CPF.';
            Session::flash('error', 'Revise o formulário. Existem campos obrigatórios ou inválidos.');
            Session::putErrors($errors);
            Session::putOldInput($_POST);
            $this->redirectTo('');
        }

       try {
        $admissionId = Admission::create([
            'consent' => 1,
            'race' => $_POST['race'],
            'unit_name' => $_POST['unit_name'],
            'job_title' => $_POST['job_title'],
            'full_name' => $_POST['full_name'],
            'father_name' => $_POST['father_name'] ?? null,
            'mother_name' => $_POST['mother_name'],
            'birth_date' => $_POST['birth_date'],
            'marital_status' => $_POST['marital_status'],
            'is_student' => (int)($_POST['is_student'] ?? 0),
            'education_level' => $_POST['education_level'],
            'nationality' => $_POST['nationality'],
            'place_of_birth' => $_POST['place_of_birth'] ?? null,
            'personal_email' => $_POST['personal_email'],
            'phone' => preg_replace('/\D/', '', (string)$_POST['phone']),
            'emergency_contact' => preg_replace('/\D/', '', (string)$_POST['emergency_contact']),
            'address_line' => $_POST['address_line'],
            'address_number' => $_POST['address_number'],
            'neighborhood' => $_POST['neighborhood'],
            'zip_code' => preg_replace('/\D/', '', (string)$_POST['zip_code']),
            'city' => $_POST['city'],
            'address_extra' => $_POST['address_extra'] ?? null,
            'state' => strtoupper($_POST['state']),
            'rg_number' => preg_replace('/\D/', '', (string)$_POST['rg_number']),
            'rg_issue_date' => $_POST['rg_issue_date'],
            'rg_issuer' => $_POST['rg_issuer'],
            'birth_city' => $_POST['birth_city'],
            'birth_state' => strtoupper($_POST['birth_state'] ?? $_POST['state']),
            'cpf' => $cpf,
            'pis_number' => preg_replace('/\D/', '', (string)$_POST['pis_number']),
            'pis_issue_date' => $_POST['pis_issue_date'],
            'has_dependents' => (int)($_POST['has_dependents'] ?? 0),
            'dependent_has_disability' => (int)($_POST['dependent_has_disability'] ?? 0),
            'uses_transport_voucher' => 0,
            'transport_voucher_daily_value' => null,
            'uniform_size' => $_POST['uniform_size'] ?? null,
            'cref_number' => trim((string) ($_POST['cref_number'] ?? '')) !== '' ? trim((string) $_POST['cref_number']) : null,
            'professor_mei_cnpj' => trim((string) ($_POST['professor_mei_cnpj'] ?? '')) !== '' ? preg_replace('/\D/', '', (string) $_POST['professor_mei_cnpj']) : null,
            'employment_function' => null,
            'admission_date' => null,
            'dismissal_date' => null,
            'workload_hours' => null,
            'salary_amount' => null,
            'salary_type' => null,
            'bank_agency' => null,
            'bank_account' => null,
            'status' => 'recebido',
            'internal_notes' => null,
            'lgpd_consent_at' => date('Y-m-d H:i:s'),
            'submitted_ip' => $_SERVER['REMOTE_ADDR'] ?? null,
            ]);
            
            } catch (\PDOException $e) {
                if (($e->errorInfo[1] ?? null) === 1062) {
                    $errors['cpf'] = 'Já existe uma ficha cadastrada com este CPF.';
                    Session::flash('error', 'Revise o formulário. Existem campos obrigatórios ou inválidos.');
                    Session::putErrors($errors);
                    Session::putOldInput($_POST);
                    $this->redirectTo('');
                }

                throw $e;
            }

        Dependent::replaceForAdmission($admissionId, (int)($_POST['has_dependents'] ?? 0) === 1 ? ($_POST['dependents'] ?? []) : []);
        AcademicInfo::replaceForAdmission($admissionId, (int)($_POST['is_student'] ?? 0) === 1 ? ($_POST['academic'] ?? null) : null);

        foreach (['profile_photo', 'rg_front', 'rg_back', 'cref_document', 'mei_certificate', 'marriage_certificate', 'divorce_annotation', 'work_card'] as $field) {
            if (
                !isset($_FILES[$field]) ||
                (int) ($_FILES[$field]['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE
            ) {
                continue;
            }

            try {
                $payload = Upload::store($_FILES[$field], 'uploads/admissions', $allowedMimeTypes, 5);
                Attachment::upsert($admissionId, $field, $payload);
            } catch (\RuntimeException $e) {
                $errors[$field] = $e->getMessage();
                Session::flash('error', 'Revise o formulário. Houve problema no envio dos anexos.');
                Session::putErrors($errors);
                Session::putOldInput($_POST);
                $this->redirectTo('');
            }
        }

        if ((int) ($_POST['has_dependents'] ?? 0) === 1 && isset($_FILES['dependent_birth_certificates'])) {
            foreach (array_keys($_POST['dependents'] ?? []) as $index) {
                $file = $this->extractNestedUpload($_FILES['dependent_birth_certificates'], (int) $index);
                if (!$file || (int) ($file['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE) {
                    continue;
                }

                try {
                    $payload = Upload::store($file, 'uploads/admissions', $allowedMimeTypes, 5);
                    Attachment::upsert($admissionId, 'dependent_birth_certificate_' . (int) $index, $payload);
                } catch (\RuntimeException $e) {
                    $errors["dependent_birth_certificates.$index"] = $e->getMessage();
                    Session::flash('error', 'Revise o formulário. Houve problema no envio dos anexos.');
                    Session::putErrors($errors);
                    Session::putOldInput($_POST);
                    $this->redirectTo('');
                }
            }
        }

        Session::flash('success', 'Ficha enviada com sucesso.');
        $this->redirectTo('obrigado');
    }


    private function extractNestedUpload(array $filesField, int $index): ?array
    {
        if (!isset($filesField['name'][$index])) {
            return null;
        }

        return [
            'name' => $filesField['name'][$index] ?? '',
            'type' => $filesField['type'][$index] ?? '',
            'tmp_name' => $filesField['tmp_name'][$index] ?? '',
            'error' => $filesField['error'][$index] ?? UPLOAD_ERR_NO_FILE,
            'size' => $filesField['size'][$index] ?? 0,
        ];
    }

    public function success(): void
    {
        $this->view('admissions/success', ['message' => Session::getFlash('success', 'Ficha enviada com sucesso.')]);
    }
}
