<?php

declare(strict_types=1);

require dirname(__DIR__) . '/bootstrap.php';

use App\Models\AcademicInfo;
use App\Models\AdminUser;
use App\Models\Admission;
use App\Models\Attachment;
use App\Models\Dependent;
use Core\Database;

if (!in_array('--force', $argv, true)) {
    echo "Este script altera dados do banco de homologação. Rode com --force para continuar.\n";
    exit(1);
}

$pdo = Database::connection();
$pdo->beginTransaction();

try {
    $seedEmailSuffix = '@homolog.local';
    $seedDomainLike = '%' . $seedEmailSuffix;
    $seedNamePrefix = 'Teste Homologação';

    $st = $pdo->prepare('SELECT id FROM admissions WHERE personal_email LIKE :email OR full_name LIKE :name');
    $st->execute([
        'email' => $seedDomainLike,
        'name' => $seedNamePrefix . '%',
    ]);
    $admissionIds = array_map('intval', array_column($st->fetchAll(), 'id'));

    if ($admissionIds !== []) {
        $in = implode(',', array_fill(0, count($admissionIds), '?'));
        $files = $pdo->prepare("SELECT relative_path FROM attachments WHERE admission_id IN ($in)");
        $files->execute($admissionIds);
        foreach ($files->fetchAll() as $file) {
            $absolute = dirname(__DIR__) . '/storage/' . $file['relative_path'];
            if (is_file($absolute)) {
                @unlink($absolute);
            }
        }

        $delete = $pdo->prepare("DELETE FROM admissions WHERE id IN ($in)");
        $delete->execute($admissionIds);
    }

    $seedAdmins = [
        ['name' => 'Administrador RH', 'email' => 'admin@empresa.com', 'password' => 'TroqueEssaSenha123!', 'role' => 'admin', 'is_active' => 1],
        ['name' => 'Homologação RH', 'email' => 'homologacao@empresa.com', 'password' => 'Homologacao123!', 'role' => 'admin', 'is_active' => 1],
        ['name' => 'Operador RH', 'email' => 'operador@empresa.com', 'password' => 'Operador123!', 'role' => 'operador', 'is_active' => 1],
        ['name' => 'Usuário Inativo', 'email' => 'inativo@empresa.com', 'password' => 'Inativo123!', 'role' => 'operador', 'is_active' => 0],
    ];

    foreach ($seedAdmins as $admin) {
        $existing = AdminUser::findByEmail($admin['email']);
        $payload = [
            'name' => $admin['name'],
            'email' => $admin['email'],
            'password_hash' => password_hash($admin['password'], PASSWORD_DEFAULT),
            'role' => $admin['role'],
            'is_active' => $admin['is_active'],
        ];

        if ($existing) {
            AdminUser::updateProfile((int) $existing['id'], [
                'name' => $payload['name'],
                'email' => $payload['email'],
                'password_hash' => $payload['password_hash'],
                'role' => $payload['role'],
                'is_active' => $payload['is_active'],
            ]);
        } else {
            AdminUser::create($payload);
        }
    }

    $records = [
        [
            'full_name' => 'Teste Homologação Simples',
            'cpf' => validCpfFromBase('111111111'),
            'email' => 'simples' . $seedEmailSuffix,
            'status' => 'recebido',
            'is_student' => 0,
            'has_dependents' => 0,
            'uses_transport_voucher' => 0,
        ],
        [
            'full_name' => 'Teste Homologação Dependentes',
            'cpf' => validCpfFromBase('222222222'),
            'email' => 'dependentes' . $seedEmailSuffix,
            'status' => 'em_analise',
            'is_student' => 0,
            'has_dependents' => 1,
            'uses_transport_voucher' => 1,
        ],
        [
            'full_name' => 'Teste Homologação Estágio',
            'cpf' => validCpfFromBase('333333333'),
            'email' => 'estagio' . $seedEmailSuffix,
            'status' => 'pendente',
            'is_student' => 1,
            'has_dependents' => 1,
            'uses_transport_voucher' => 1,
        ],
    ];

    foreach ($records as $index => $record) {
        $admissionId = Admission::create([
            'consent' => 1,
            'race' => 'parda',
            'unit_name' => 'Unidade Teste ' . ($index + 1),
            'job_title' => $index === 2 ? 'Estagiário' : 'Assistente Administrativo',
            'full_name' => $record['full_name'],
            'father_name' => 'Pai Teste',
            'mother_name' => 'Mãe Teste',
            'birth_date' => '1999-05-10',
            'marital_status' => 'solteiro',
            'is_student' => $record['is_student'],
            'education_level' => $record['is_student'] ? 'superior_cursando' : 'medio_completo',
            'nationality' => 'Brasileira',
            'place_of_birth' => 'São Paulo',
            'personal_email' => $record['email'],
            'phone' => '11999999999',
            'emergency_contact' => '11988888888',
            'address_line' => 'Rua de Teste',
            'address_number' => '100',
            'neighborhood' => 'Centro',
            'zip_code' => '01001000',
            'city' => 'São Paulo',
            'address_extra' => 'Sala 1',
            'state' => 'SP',
            'rg_number' => '123456789',
            'rg_issue_date' => '2020-01-10',
            'rg_issuer' => 'SSP',
            'birth_city' => 'São Paulo',
            'birth_state' => 'SP',
            'cpf' => $record['cpf'],
            'pis_number' => '12345678901',
            'pis_issue_date' => '2020-02-01',
            'has_dependents' => $record['has_dependents'],
            'dependent_has_disability' => $record['has_dependents'] ? 1 : 0,
            'uses_transport_voucher' => $record['uses_transport_voucher'],
            'transport_voucher_daily_value' => $record['uses_transport_voucher'] ? '12.50' : null,
            'uniform_size' => 'M',
            'employment_function' => $index === 2 ? 'Estagiário Ed. Física' : 'Assistente de RH',
            'admission_date' => '2025-05-26',
            'dismissal_date' => $index === 2 ? '2026-05-26' : null,
            'workload_hours' => $index === 2 ? '30' : '44',
            'salary_amount' => $index === 2 ? '1000.00' : '2200.00',
            'salary_type' => 'mensal',
            'bank_agency' => '1234',
            'bank_account' => '12345-6',
            'status' => $record['status'],
            'internal_notes' => 'Registro gerado automaticamente para homologação.',
            'lgpd_consent_at' => date('Y-m-d H:i:s'),
            'submitted_ip' => '127.0.0.1',
        ]);

        if ($record['has_dependents']) {
            Dependent::replaceForAdmission($admissionId, [
                [
                    'full_name' => 'Dependente Um',
                    'birth_date' => '2018-01-15',
                    'cpf' => validCpfFromBase('444444444'),
                    'birth_city' => 'São Paulo',
                    'has_disability' => 1,
                ],
                [
                    'full_name' => 'Dependente Dois',
                    'birth_date' => '2020-06-20',
                    'cpf' => validCpfFromBase('555555555'),
                    'birth_city' => 'Guarulhos',
                    'has_disability' => 0,
                ],
            ]);
        }

        if ($record['is_student']) {
            AcademicInfo::replaceForAdmission($admissionId, [
                'internship_nature' => 'Obrigatório',
                'academic_level' => 'Superior',
                'institution_name' => 'Faculdade Teste',
                'institution_cnpj' => '12345678000199',
                'institution_address' => 'Av. Faculdade',
                'institution_neighborhood' => 'Centro',
                'institution_number' => '500',
                'institution_zip' => '01002000',
                'institution_city' => 'São Paulo',
                'institution_state' => 'SP',
                'advisor_name' => 'Prof. Teste',
                'semester' => '5º',
                'course_name' => 'Administração',
                'registration_number' => 'RGM123456',
            ]);
        }

        seedAttachment($admissionId, 'profile_photo', 'foto-perfil-teste.png', tinyPng(), 'image/png');
        seedAttachment($admissionId, 'rg_front', 'rg-frente-teste.png', tinyPng(), 'image/png');
        seedAttachment($admissionId, 'rg_back', 'rg-verso-teste.pdf', tinyPdf(), 'application/pdf');
    }

    $pdo->commit();
    echo "Massa de homologação criada/atualizada com sucesso.\n";
    echo "Usuários: admin@empresa.com / TroqueEssaSenha123! | homologacao@empresa.com / Homologacao123! | operador@empresa.com / Operador123!\n";
} catch (Throwable $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    fwrite(STDERR, 'Falha ao criar massa de homologação: ' . $e->getMessage() . "\n");
    exit(1);
}

function seedAttachment(int $admissionId, string $labelKey, string $originalName, string $binary, string $mime): void
{
    $relativeDir = 'uploads/admissions/' . date('Y/m');
    $absoluteDir = dirname(__DIR__) . '/storage/' . $relativeDir;

    if (!is_dir($absoluteDir)) {
        mkdir($absoluteDir, 0775, true);
    }

    $extension = pathinfo($originalName, PATHINFO_EXTENSION);
    $storedName = bin2hex(random_bytes(12)) . '.' . $extension;
    $absolutePath = $absoluteDir . '/' . $storedName;
    file_put_contents($absolutePath, $binary);

    Attachment::upsert($admissionId, $labelKey, [
        'original_name' => $originalName,
        'stored_name' => $storedName,
        'relative_path' => $relativeDir . '/' . $storedName,
        'mime_type' => $mime,
        'size_bytes' => strlen($binary),
    ]);
}

function tinyPng(): string
{
    return base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAusB9sY9nS8AAAAASUVORK5CYII=');
}

function tinyPdf(): string
{
    return "%PDF-1.4\n1 0 obj<<>>endobj\n2 0 obj<< /Type /Catalog /Pages 3 0 R >>endobj\n3 0 obj<< /Type /Pages /Count 1 /Kids [4 0 R] >>endobj\n4 0 obj<< /Type /Page /Parent 3 0 R /MediaBox [0 0 300 144] /Contents 5 0 R /Resources << /Font << /F1 6 0 R >> >> >>endobj\n5 0 obj<< /Length 44 >>stream\nBT /F1 12 Tf 72 100 Td (RG verso de homologacao) Tj ET\nendstream\nendobj\n6 0 obj<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>endobj\nxref\n0 7\n0000000000 65535 f \n0000000009 00000 n \n0000000030 00000 n \n0000000087 00000 n \n0000000144 00000 n \n0000000270 00000 n \n0000000364 00000 n \ntrailer<< /Size 7 /Root 2 0 R >>\nstartxref\n434\n%%EOF";
}

function validCpfFromBase(string $base9): string
{
    $cpf = preg_replace('/\D/', '', $base9);
    $cpf = str_pad(substr($cpf, 0, 9), 9, '0', STR_PAD_RIGHT);

    for ($t = 9; $t < 11; $t++) {
        $sum = 0;
        for ($i = 0; $i < $t; $i++) {
            $sum += (int) $cpf[$i] * (($t + 1) - $i);
        }
        $digit = ((10 * $sum) % 11) % 10;
        $cpf .= (string) $digit;
    }

    return $cpf;
}
