<?php

declare(strict_types=1);

namespace App\Models;

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

/**
 * Distribucion de Utilidades por Periodo.
 *
 * Representa un evento de distribucion de utilidades para un periodo contable.
 * Contiene el snapshot financiero de la compania al momento de la distribucion
 * y las lineas individuales por socio.
 *
 * Flujo:
 * 1. DRAFT: Se crea el borrador con el calculo de utilidades del periodo.
 * 2. APPROVED: Un admin aprueba la distribucion.
 * 3. DISTRIBUTED: Se ejecutan los pagos (se crean PartnerWithdrawal + Expense).
 * 4. CANCELLED: Se anula si hay errores antes de distribuir.
 *
 * @property int $id
 * @property int $company_id
 * @property Carbon $period_start
 * @property Carbon $period_end
 * @property string $total_revenue
 * @property string $total_expenses
 * @property string $net_profit
 * @property string $distributable_profit
 * @property string $retained_amount
 * @property ProfitDistributionStatus $status
 * @property int|null $approved_by_user_id
 * @property Carbon|null $approved_at
 * @property Carbon|null $distributed_at
 * @property int $user_id
 * @property string|null $notes
 * @property array|null $metadata
 */
class ProfitDistribution extends Model
{
    use MultiTenantScope;

    protected $fillable = [
        'company_id',
        'period_start',
        'period_end',
        'total_revenue',
        'total_expenses',
        'net_profit',
        'distributable_profit',
        'retained_amount',
        'status',
        'approved_by_user_id',
        'approved_at',
        'distributed_at',
        'user_id',
        'notes',
        'metadata',
    ];

    protected $casts = [
        'period_start' => 'date',
        'period_end' => 'date',
        'total_revenue' => 'decimal:2',
        'total_expenses' => 'decimal:2',
        'net_profit' => 'decimal:2',
        'distributable_profit' => 'decimal:2',
        'retained_amount' => 'decimal:2',
        'status' => ProfitDistributionStatus::class,
        'approved_at' => 'datetime',
        'distributed_at' => 'datetime',
        'metadata' => 'array',
    ];

    protected $attributes = [
        'status' => 'draft',
        'retained_amount' => '0.00',
    ];

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

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

    public function lines(): HasMany
    {
        return $this->hasMany(ProfitDistributionLine::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 getNetProfitMoney(): Money
    {
        return Money::of($this->net_profit);
    }

    public function getDistributableProfitMoney(): Money
    {
        return Money::of($this->distributable_profit);
    }

    public function isDraft(): bool
    {
        return $this->status === ProfitDistributionStatus::DRAFT;
    }

    public function isDistributed(): bool
    {
        return $this->status === ProfitDistributionStatus::DISTRIBUTED;
    }

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

    public function scopeOfStatus($query, ProfitDistributionStatus $status)
    {
        return $query->where('status', $status->value);
    }
}
