<?php

declare(strict_types=1);

namespace App\Models;

use App\Enums\WithdrawalType;
use App\Traits\MultiTenantScope;
use App\ValueObjects\Money;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * Retiro de un Socio/Inversionista.
 *
 * Tipos:
 * - profit_withdrawal: Retiro de utilidades (reduce utilidades retenidas, NO capital)
 * - capital_return: Devolucion de capital (reduce capital invertido)
 * - dividend_payment: Pago de dividendos (reduce utilidades retenidas)
 *
 * Se vincula a un registro de Expense para integridad contable.
 * Requiere aprobacion por defecto.
 *
 * @property int $id
 * @property int $company_id
 * @property int $partner_id
 * @property string $amount
 * @property WithdrawalType $type
 * @property string|null $method
 * @property Carbon $operation_date
 * @property string|null $reference
 * @property string|null $notes
 * @property array|null $metadata
 * @property int|null $expense_id
 * @property string $approval_status
 * @property int|null $approved_by_user_id
 * @property Carbon|null $approved_at
 * @property string|null $approval_notes
 * @property int $user_id
 * @property bool $is_locked
 * @property Carbon|null $locked_at
 */
class PartnerWithdrawal extends Model
{
    use MultiTenantScope;

    protected $fillable = [
        'company_id',
        'partner_id',
        'amount',
        'type',
        'method',
        'operation_date',
        'reference',
        'notes',
        'metadata',
        'expense_id',
        'approval_status',
        'approved_by_user_id',
        'approved_at',
        'approval_notes',
        'user_id',
        'is_locked',
        'locked_at',
        'idempotency_key',
    ];

    protected $casts = [
        'amount' => 'decimal:2',
        'type' => WithdrawalType::class,
        'operation_date' => 'date',
        'metadata' => 'array',
        'is_locked' => 'boolean',
        'locked_at' => 'datetime',
        'approved_at' => 'datetime',
    ];

    protected $attributes = [
        'approval_status' => 'pending',
        'is_locked' => false,
    ];

    // ═══════════════════════════════════════════════════════════════════════
    // RELATIONSHIPS
    // ═══════════════════════════════════════════════════════════════════════

    public function company(): BelongsTo
    {
        return $this->belongsTo(Company::class);
    }

    public function partner(): BelongsTo
    {
        return $this->belongsTo(Partner::class);
    }

    public function expense(): BelongsTo
    {
        return $this->belongsTo(Expense::class);
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    public function approvedBy(): BelongsTo
    {
        return $this->belongsTo(User::class, 'approved_by_user_id');
    }

    // ═══════════════════════════════════════════════════════════════════════
    // HELPERS
    // ═══════════════════════════════════════════════════════════════════════

    public function getAmountMoney(): Money
    {
        return Money::of($this->amount);
    }

    public function isPending(): bool
    {
        return $this->approval_status === 'pending';
    }

    public function isApproved(): bool
    {
        return $this->approval_status === 'approved';
    }

    public function isRejected(): bool
    {
        return $this->approval_status === 'rejected';
    }

    // ═══════════════════════════════════════════════════════════════════════
    // SCOPES
    // ═══════════════════════════════════════════════════════════════════════

    public function scopeApproved($query)
    {
        return $query->where('approval_status', 'approved');
    }

    public function scopePending($query)
    {
        return $query->where('approval_status', 'pending');
    }
}
