<?php

require_once __DIR__ . '/DB.php';
require_once __DIR__ . '/GeocodeService.php';

class AdoptionService
{
    public static function adopt(array $data): void
    {
        $db = DB::pdo();
        $db->beginTransaction();

        try {
            $animalId = (int) $data['animal_id'];
            $date = $data['adoption_date'] ?? date('Y-m-d');
            $beforeStmt = $db->prepare(
                'SELECT status,refuge_room,care_box_key,current_address FROM animals WHERE id=:id',
            );
            $beforeStmt->execute([':id' => $animalId]);
            $beforeLocation = $beforeStmt->fetch(PDO::FETCH_ASSOC) ?: [];

            // 1. Enregistrement de l’adoption
            $stmt = $db->prepare('
            INSERT INTO adoptions (
                animal_id,
                adopter_name,
                adopter_phone,
                adopter_email,
                adopter_address,
                adopter_postal_code,
                adopter_city,
                adoption_date,
                notes,
                adopter_contact_id,
                created_at
            ) VALUES (
                :animal_id,
                :name,
                :phone,
                :email,
                :address,
                :postal,
                :city,
                :date,
                :notes,
                :contact_id,
                CURRENT_TIMESTAMP
            )
            ');

            $stmt->execute([
                ':animal_id' => $animalId,
                ':name' => $data['adopter_name'],
                ':phone' => $data['adopter_phone'] ?: null,
                ':email' => $data['adopter_email'] ?: null,
                ':address' => $data['adopter_address'] ?: null,
                ':postal' => $data['adopter_postal_code'] ?: null,
                ':city' => $data['adopter_city'] ?: null,
                ':date' => $date,
                ':notes' => $data['notes'] ?: null,
                ':contact_id' => $data['adopter_contact_id'] ?? null,
            ]);
            $adoptionId = (int) $db->lastInsertId();
            $db->prepare(
                "INSERT INTO animal_placements(animal_id,event_type,event_date,contact_id,reason,notes,adoption_id,created_by) VALUES(:animal,'adoption',:date,:contact,'Adoption définitive',:notes,:adoption,:user)",
            )->execute([
                ':animal' => $animalId,
                ':date' => $date,
                ':contact' => $data['adopter_contact_id'] ?? null,
                ':notes' => $data['notes'] ?: null,
                ':adoption' => $adoptionId,
                ':user' => Auth::id(),
            ]);

            // 2. Mise à jour du statut de l’animal
            $currentAddress = implode(
                ' ',
                array_filter([
                    $data['adopter_address'] ?? '',
                    $data['adopter_postal_code'] ?? '',
                    $data['adopter_city'] ?? '',
                ]),
            );

            $lat = null;
            $lng = null;

            if (!empty($currentAddress)) {
                $coords = GeocodeService::geocode($currentAddress);

                if ($coords) {
                    $lat = $coords['lat'] ?? null;
                    $lng = $coords['lng'] ?? null;
                }
            }

            $db->prepare(
                "
            UPDATE animals
            SET
            status = 'adopte',
            refuge_room = NULL,
            care_box_key = NULL,
            updated_at = CURRENT_TIMESTAMP,
            current_address = :currentAddress,
            current_lat = :lat,
            current_lng = :lng
            WHERE id = :id
            ",
            )->execute([':id' => $animalId, ':currentAddress' => $currentAddress, ':lat' => $lat, ':lng' => $lng]);

            LocationHistoryService::record(
                $db,
                $animalId,
                $beforeLocation,
                [
                    'status' => 'adopte',
                    'refuge_room' => null,
                    'care_box_key' => null,
                    'current_address' => $currentAddress,
                ],
                'adoption',
                'Adoption finalisée',
                $date . ' 12:00:00',
            );

            // 3. Ajout dans les mouvements administratifs (sortie)
            $stmt = $db->prepare("
            INSERT INTO animal_movements (
                animal_id,
                kind,
                place,
                lieu,
                contact_name,
                contact_phone,
                contact_email,
                note,
                created_at
            ) VALUES (
                :animal_id,
                'exit',
                :place,
                'Adoption',
                :contact_name,
                :contact_phone,
                :contact_email,
                :note,
                CURRENT_TIMESTAMP
            )
            ");

            $stmt->execute([
                ':animal_id' => $animalId,
                ':place' => $data['adopter_address'] ?: null,
                ':contact_name' => $data['adopter_name'] ?: null,
                ':contact_phone' => $data['adopter_phone'] ?: null,
                ':contact_email' => $data['adopter_email'] ?: null,
                ':note' => 'Adoption finalisée',
            ]);

            // 4. Ajout dans l’historique
            $stmt = $db->prepare("
            INSERT INTO animal_history (
                animal_id,
                type,
                label,
                details,
                user_id,
                created_at
            ) VALUES (
                :animal_id,
                'adoption',
                'Adoption finalisée',
                :details,
                :user_id,
                CURRENT_TIMESTAMP
            )
            ");

            $stmt->execute([
                ':animal_id' => $animalId,
                ':details' => 'Par ' . $data['adopter_name'] . ' - Note(s) : ' . $data['notes'],
                ':user_id' => Auth::id(),
            ]);

            $db->commit();
        } catch (Exception $e) {
            $db->rollBack();
            throw $e;
        }
    }
}
