<?php

namespace App\Models;

use App\Scopes\ViewPermissionScope;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Facades\Auth;

class PerformanceCard extends Model
{
    use HasFactory;

    const PROJECT_MANNER_DEVELOPMENTAL = 'DEVELOPMENTAL';

    const PROJECT_MANNER_SUPPORT = 'SUPPORT';

    const PROJECT_MANNER_EMPOWERMENT = 'EMPOWERMENT';

    const PROJECT_MANNER_INVESTMENT = 'INVESTMENT';

    protected $fillable = [
        'department_id',
        'project_manner',
        'goal',
        'created_by',
    ];

    protected $casts = [
        'project_manner' => 'string',
    ];

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

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

    public function products(): BelongsToMany
    {
        return $this->belongsToMany(SekayaValue::class, 'performance_card_sekaya_value')
            ->where('type', SekayaValue::TYPE_PERFORMANCE_CARD_PRODUCT);
    }

    public function results(): HasMany
    {
        return $this->hasMany(PerformanceCardResult::class);
    }

    public function assignees(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'performance_card_user');
    }

    public function wallet(): HasOne
    {
        return $this->hasOne(PerformanceWallet::class);
    }

    public function initiatives(): HasManyThrough
    {
        return $this->hasManyThrough(Initiative::class, PerformanceWallet::class);
    }

    /**
     * Get available project manners
     */
    public static function getProjectManners(): array
    {
        return [
            self::PROJECT_MANNER_DEVELOPMENTAL => __('performance_card.developmental'),
            self::PROJECT_MANNER_SUPPORT => __('performance_card.support'),
            self::PROJECT_MANNER_EMPOWERMENT => __('performance_card.empowerment'),
            self::PROJECT_MANNER_INVESTMENT => __('performance_card.investment'),
        ];
    }

    /**
     * Get the overall progress of all initiatives in this performance card
     * Calculates average progress from all initiatives
     */
    public function getOverallProgressAttribute(): float
    {
        $initiatives = $this->initiatives;

        if ($initiatives->isEmpty()) {
            return 0;
        }

        $totalProgress = 0;
        foreach ($initiatives as $initiative) {
            $totalProgress += $initiative->overall_progress;
        }

        return $totalProgress / $initiatives->count();
    }

    /**
     * Get the total expected cost of all initiatives in this performance card
     */
    public function getExpectedCostAttribute(): float
    {
        $initiatives = $this->initiatives;

        if ($initiatives->isEmpty()) {
            return 0;
        }

        $totalExpectedCost = 0;
        foreach ($initiatives as $initiative) {
            $totalExpectedCost += ($initiative->expected_cost ?? 0);
        }

        return $totalExpectedCost;
    }

    /**
     * Get the total emergency reserve of all initiatives in this performance card
     */
    public function getEmergencyReserveAttribute(): float
    {
        $initiatives = $this->initiatives;

        if ($initiatives->isEmpty()) {
            return 0;
        }

        $totalEmergencyReserve = 0;
        foreach ($initiatives as $initiative) {
            $totalEmergencyReserve += ($initiative->emergency_reserve ?? 0);
        }

        return $totalEmergencyReserve;
    }

    /**
     * Get the total estimated budget (expected cost + emergency reserve) of all initiatives in this performance card
     */
    public function getEstimatedBudgetAttribute(): float
    {
        return $this->expected_cost + $this->emergency_reserve;
    }

    /**
     * Get the actual cost based on all related initiatives' actual costs
     */
    public function getActualCostAttribute(): float
    {
        $initiatives = $this->initiatives;

        if ($initiatives->isEmpty()) {
            return 0;
        }

        $totalActualCost = 0;
        foreach ($initiatives as $initiative) {
            $totalActualCost += $initiative->actual_cost;
        }

        return $totalActualCost;
    }

    /**
     * Get the reserve status (always 0 as requested)
     */
    public function getReserveStatusAttribute(): float
    {
        return 0;
    }

    /**
     * Get the total expenses (actual cost + reserve status)
     */
    public function getTotalExpensesAttribute(): float
    {
        return $this->actual_cost + $this->reserve_status;
    }

    /**
     * Get the financial completion percentage based on actual cost vs expected cost
     */
    public function getFinancialCompletionPercentageAttribute(): float
    {
        if (! $this->expected_cost || $this->expected_cost <= 0) {
            return 0;
        }

        return min(100, ($this->actual_cost / $this->expected_cost) * 100);
    }

    /**
     * Boot the model
     */
    protected static function booted()
    {
        static::addGlobalScope(new ViewPermissionScope);
    }

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            if (Auth::check()) {
                $model->created_by = Auth::id();
            }
        });
    }
}
