<?php

declare(strict_types=1);

namespace App\Observers;

use App\Models\CollectorCreditOrder;
use App\Models\Credit;
use App\Services\CollectorCreditOrderService;
use Illuminate\Support\Facades\DB;

class CreditObserver
{
    public function __construct(
        private readonly CollectorCreditOrderService $orderService,
    ) {}

    /**
     * Cuando se crea un crédito con collector asignado,
     * agregar a la ruta del collector respetando el historial de posición del cliente.
     */
    public function created(Credit $credit): void
    {
        if ($credit->collector_user_id && in_array($credit->status, Credit::ACTIVE_STATUSES, true)) {
            $this->orderService->insertRespectingHistory($credit->company_id, $credit->collector_user_id, $credit->id, $credit->client_id);
        }
    }

    /**
     * Al actualizar un crédito, manejar:
     * 1. Cambio de collector → mover order row
     * 2. Cambio a estado cerrado → eliminar order row (guardando posición histórica)
     * 3. Cambio a estado activo → agregar order row si no existe
     */
    public function updated(Credit $credit): void
    {
        $statusChanged = $credit->wasChanged('status');
        $collectorChanged = $credit->wasChanged('collector_user_id');

        // Cambio de collector
        if ($collectorChanged) {
            $oldCollectorId = $credit->getOriginal('collector_user_id');
            $newCollectorId = $credit->collector_user_id;

            // Eliminar row del collector anterior y re-indexar (guarda posición histórica)
            if ($oldCollectorId) {
                $this->orderService->removeAndReindex($credit->company_id, $oldCollectorId, $credit->id, $credit->client_id);
            }

            // Agregar al nuevo collector si el crédito está activo
            if ($newCollectorId && in_array($credit->status, Credit::ACTIVE_STATUSES, true)) {
                $this->orderService->insertRespectingHistory($credit->company_id, $newCollectorId, $credit->id, $credit->client_id);
            }

            return;
        }

        // Cambio de estado
        if ($statusChanged) {
            $isNowActive = in_array($credit->status, Credit::ACTIVE_STATUSES, true);
            $wasActive = in_array($credit->getOriginal('status'), Credit::ACTIVE_STATUSES, true);

            // Cerrado → eliminar row y re-indexar (guarda posición histórica)
            if ($wasActive && ! $isNowActive && $credit->collector_user_id) {
                $this->orderService->removeAndReindex($credit->company_id, $credit->collector_user_id, $credit->id, $credit->client_id);
            }

            // Reactivado → agregar row respetando historial
            if (! $wasActive && $isNowActive && $credit->collector_user_id) {
                $this->orderService->insertRespectingHistory($credit->company_id, $credit->collector_user_id, $credit->id, $credit->client_id);
            }
        }
    }

    /**
     * Al eliminar un crédito, guardar posición histórica, limpiar su order row y re-indexar.
     */
    public function deleted(Credit $credit): void
    {
        DB::transaction(function () use ($credit): void {
            // Guardar posición histórica antes de borrar
            if ($credit->collector_user_id) {
                $this->orderService->saveHistoricalPosition($credit->company_id, $credit->collector_user_id, $credit->id, $credit->client_id);
            }

            // Limpieza defensiva sin filtrar por user_id: captura filas residuales
            // de cambios de collector anteriores que no se limpiaron correctamente.
            CollectorCreditOrder::where('credit_id', $credit->id)->delete();

            if ($credit->collector_user_id) {
                $this->orderService->reindexCollector($credit->company_id, $credit->collector_user_id);
            }
        });
    }
}
