#!/usr/bin/env php
<?php
declare(strict_types=1);

$root = dirname(__DIR__);
require $root . '/app/Services/DB.php';
require $root . '/app/Services/BackupService.php';
$apply = in_array('--apply', $argv, true);
$db = DB::pdo();
$backup = null;
$user =
    (int) ($db->query("SELECT id FROM users WHERE role='admin' AND active=1 ORDER BY id LIMIT 1")->fetchColumn() ?:
    0) ?:
    null;
$latest = $db
    ->query(
        "WITH ranked AS (SELECT ap.*,ROW_NUMBER() OVER(PARTITION BY animal_id ORDER BY date(event_date) DESC,id DESC) rn FROM animal_placements ap) SELECT r.*,a.status current_status,a.archived_at current_archived,dc.name contact_name,dc.address contact_address,dc.postal_code contact_postal,dc.city contact_city,ad.adopter_address,ad.adopter_postal_code,ad.adopter_city FROM ranked r JOIN animals a ON a.id=r.animal_id LEFT JOIN animal_deaths d ON d.animal_id=a.id LEFT JOIN directory_contacts dc ON dc.id=r.contact_id LEFT JOIN adoptions ad ON ad.id=r.adoption_id WHERE r.rn=1 AND r.event_type='adoption' AND d.animal_id IS NULL AND a.deleted_at IS NULL ORDER BY r.event_date,r.animal_id",
    )
    ->fetchAll(PDO::FETCH_ASSOC);
$summary = [
    'adopted_states_checked' => count($latest),
    'statuses_fixed' => 0,
    'locations_fixed' => 0,
    'movements_created' => 0,
    'movements_updated' => 0,
    'history_created' => 0,
];
if ($apply) {
    $backup = BackupService::create('avant-reconciliation-etat-animaux');
}
$db->beginTransaction();
try {
    foreach ($latest as $row) {
        $animal = (int) $row['animal_id'];
        $date = (string) $row['event_date'];
        $contact = trim((string) ($row['contact_name'] ?? '')) ?: 'Adoptant non renseigné';
        $address = implode(
            ' ',
            array_filter([
                trim((string) ($row['contact_address'] ?? '' ?: $row['adopter_address'] ?? '')),
                trim((string) ($row['contact_postal'] ?? '' ?: $row['adopter_postal_code'] ?? '')),
                trim((string) ($row['contact_city'] ?? '' ?: $row['adopter_city'] ?? '')),
            ]),
        );
        if ($address === '') {
            $address = 'Adopté par ' . $contact;
        }
        if ($row['current_status'] !== 'adopte' || empty($row['current_archived'])) {
            $summary['statuses_fixed']++;
        }
        $current = $db->prepare('SELECT current_address FROM animals WHERE id=?');
        $current->execute([$animal]);
        if (trim((string) $current->fetchColumn()) !== $address) {
            $summary['locations_fixed']++;
        }
        $db->prepare(
            "UPDATE animals SET status='adopte',is_archived=1,archived_at=?,refuge_room=NULL,care_box_key=NULL,quarantine_until=NULL,current_address=?,current_lat=NULL,current_lng=NULL,updated_at=datetime('now') WHERE id=?",
        )->execute([$date . ' 12:00:00', $address, $animal]);
        $movement = $db->prepare(
            "SELECT id FROM animal_movements WHERE animal_id=? AND kind='exit' AND lower(COALESCE(lieu,'')) LIKE 'adopt%' ORDER BY created_at DESC,id DESC LIMIT 1",
        );
        $movement->execute([$animal]);
        $movementId = (int) $movement->fetchColumn();
        if ($movementId) {
            $db->prepare(
                "UPDATE animal_movements SET place=?,lieu='Adoption',contact_name=?,note=CASE WHEN note IS NULL OR note='' THEN 'Sortie synchronisée avec le parcours d’adoption.' ELSE note END,created_at=? WHERE id=?",
            )->execute([$address, $contact, $date . ' 12:00:00', $movementId]);
            $summary['movements_updated']++;
        } else {
            $db->prepare(
                "INSERT INTO animal_movements(animal_id,kind,place,lieu,contact_name,note,created_at) VALUES(?,'exit',?,'Adoption',?,'Sortie synchronisée avec le parcours d’adoption.',?)",
            )->execute([$animal, $address, $contact, $date . ' 12:00:00']);
            $summary['movements_created']++;
        }
        $history = $db->prepare(
            "SELECT 1 FROM animal_history WHERE animal_id=? AND date(created_at)=date(?) AND (lower(label) LIKE '%adopt%' OR lower(type)='adoption') LIMIT 1",
        );
        $history->execute([$animal, $date]);
        if (!$history->fetchColumn()) {
            $db->prepare(
                "INSERT INTO animal_history(animal_id,type,label,details,user_id,created_at) VALUES(?,'status','Adoption de l’animal',?,?,?)",
            )->execute([$animal, 'Adopté par ' . $contact . '.', $user, $date . ' 12:00:00']);
            $summary['history_created']++;
        }
    }
    $fk = $db->query('PRAGMA foreign_key_check')->fetchAll();
    if ($fk) {
        throw new RuntimeException('Violation de clé étrangère après synchronisation.');
    }
    if ($apply) {
        $db->commit();
    } else {
        $db->rollBack();
    }
    echo json_encode(
    ['mode' => $apply ? 'APPLIQUE' : 'SIMULATION', 'backup' => $backup['name'] ?? null, 'summary' => $summary],
    JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,
),
        "\n";
} catch (Throwable $error) {
    if ($db->inTransaction()) {
        $db->rollBack();
    }
    fwrite(STDERR, 'Synchronisation interrompue : ' . $error->getMessage() . "\n");
    exit(1);
}
