<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;

class ExternalPartnerMovement extends Model
{
    public const TYPE_CEDIDA = 'cedida';
    public const TYPE_CAMBIO_INMEDIATO = 'cambio_inmediato';
    public const TYPE_CAMBIO_PENDIENTE = 'cambio_pendiente';
    public const TYPE_COMPENSACION_SERENATA = 'compensacion_serenata';
    public const TYPE_AJUSTE_EFECTIVO = 'ajuste_efectivo';
    public const TYPE_PENALIDAD = 'penalidad';
    public const TYPE_REGULARIZACION = 'regularizacion';

    public const DIRECTION_OWNER_CREDIT = 'a_favor_mio';
    public const DIRECTION_OWNER_DEBIT = 'yo_debo';

    public const SETTLEMENT_PENDING = 'pendiente';
    public const SETTLEMENT_CASH = 'efectivo';
    public const SETTLEMENT_SERENATA = 'serenata';
    public const SETTLEMENT_MIXED = 'mixta';

    protected $fillable = [
        'organization_id',
        'serenata_id',
        'external_partner_id',
        'created_by_user_id',
        'movement_type',
        'settlement_kind',
        'direction',
        'amount',
        'signed_amount',
        'counterpart_reference',
        'due_date',
        'notes',
        'status',
    ];

    protected $casts = [
        'organization_id' => 'integer',
        'serenata_id' => 'integer',
        'external_partner_id' => 'integer',
        'created_by_user_id' => 'integer',
        'amount' => 'float',
        'signed_amount' => 'float',
        'due_date' => 'date',
    ];

    public static function typeOptions(): array
    {
        return [
            self::TYPE_CEDIDA => 'Cedida',
            self::TYPE_CAMBIO_INMEDIATO => 'Cambio inmediato',
            self::TYPE_CAMBIO_PENDIENTE => 'Cambio pendiente',
            self::TYPE_COMPENSACION_SERENATA => 'Compensación con serenata',
            self::TYPE_AJUSTE_EFECTIVO => 'Ajuste en efectivo',
            self::TYPE_PENALIDAD => 'Penalidad',
            self::TYPE_REGULARIZACION => 'Regularización',
        ];
    }

    public static function directionOptions(): array
    {
        return [
            self::DIRECTION_OWNER_CREDIT => 'El externo me debe',
            self::DIRECTION_OWNER_DEBIT => 'Yo le debo al externo',
        ];
    }

    public static function settlementOptions(): array
    {
        return [
            self::SETTLEMENT_PENDING => 'Pendiente',
            self::SETTLEMENT_CASH => 'Efectivo / transferencia',
            self::SETTLEMENT_SERENATA => 'Serenata',
            self::SETTLEMENT_MIXED => 'Mixta',
        ];
    }

    public static function signedAmountFromDirection(string $direction, float $amount): float
    {
        $normalizedAmount = round(max(0, $amount), 2);

        return $direction === self::DIRECTION_OWNER_DEBIT
            ? -1 * $normalizedAmount
            : $normalizedAmount;
    }

    public static function summarizeBalance(Collection $movements): array
    {
        $balance = round((float) $movements->sum('signed_amount'), 2);

        if ($balance > 0) {
            return [
                'status' => 'a_favor',
                'label' => 'Te deben',
                'amount' => $balance,
            ];
        }

        if ($balance < 0) {
            return [
                'status' => 'en_contra',
                'label' => 'Debes',
                'amount' => abs($balance),
            ];
        }

        return [
            'status' => 'equilibrado',
            'label' => 'Saldo en cero',
            'amount' => 0.0,
        ];
    }

    public function serenata()
    {
        return $this->belongsTo(Serenata::class);
    }

    public function externalPartner()
    {
        return $this->belongsTo(ExternalPartner::class);
    }

    public function createdByUser()
    {
        return $this->belongsTo(User::class, 'created_by_user_id');
    }
}
