<?php

namespace App\Domain\Inventory\Models;

use App\Domain\Shared\Traits\BelongsToAcademy;
use App\Domain\Shared\Traits\HasUuid;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class ProductInstallmentPlan extends Model
{
    use BelongsToAcademy, HasUuid;

    protected $fillable = [
        'academy_id',
        'product_id',
        'membership_tier',
        'label_ar',
        'installments',
        'frequency',
        'down_payment_pct',
        'installment_amounts',
        'is_active',
        'sort_order',
    ];

    protected function casts(): array
    {
        return [
            'installments' => 'integer',
            'down_payment_pct' => 'integer',
            'installment_amounts' => 'array',
            'is_active' => 'boolean',
            'sort_order' => 'integer',
        ];
    }

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

    public function scopeActive(Builder $query): Builder
    {
        return $query->where('is_active', true);
    }

    public function scopeForTier(Builder $query, string $tier): Builder
    {
        return $query->where(fn ($q) =>
            $q->where('membership_tier', $tier)->orWhere('membership_tier', 'any')
        );
    }

    /**
     * Get the piaster amount for a specific slot (0-based index).
     * If an explicit amount was set for that slot, use it; otherwise auto-calculate.
     */
    public function amountForSlot(int $slotIndex, int $totalPiasters): int
    {
        $explicit = $this->installment_amounts[$slotIndex] ?? null;
        if ($explicit !== null && $explicit > 0) {
            return (int) $explicit;
        }

        // Auto-calculate based on whether this is the first slot (down payment) or regular
        if ($slotIndex === 0) {
            return $this->downPaymentAmount($totalPiasters);
        }
        return $this->regularInstallmentAmount($totalPiasters);
    }

    /** Calculate down payment amount in piasters */
    public function downPaymentAmount(int $totalPiasters): int
    {
        $explicit = $this->installment_amounts[0] ?? null;
        if ($explicit !== null && $explicit > 0) {
            return (int) $explicit;
        }
        if ($this->down_payment_pct <= 0) {
            return (int) ceil($totalPiasters / $this->installments);
        }
        return (int) ceil($totalPiasters * $this->down_payment_pct / 100);
    }

    /** Calculate per-installment amount (after down payment) in piasters */
    public function regularInstallmentAmount(int $totalPiasters): int
    {
        $remaining = $this->installments - 1;
        if ($remaining <= 0) {
            return 0;
        }
        $afterDown = $totalPiasters - $this->downPaymentAmount($totalPiasters);
        return (int) ceil($afterDown / $remaining);
    }

    /**
     * Build the full schedule of amounts for all slots.
     * Uses explicit amounts where set, auto-calculates the rest.
     */
    public function buildSchedule(int $totalPiasters): array
    {
        $schedule = [];
        $explicitSum = 0;
        $explicitSlots = [];

        // First pass: collect explicit slots
        for ($i = 0; $i < $this->installments; $i++) {
            $explicit = $this->installment_amounts[$i] ?? null;
            if ($explicit !== null && $explicit > 0) {
                $explicitSum += (int) $explicit;
                $explicitSlots[$i] = (int) $explicit;
            }
        }

        $autoSlots = $this->installments - count($explicitSlots);
        $remainingForAuto = max(0, $totalPiasters - $explicitSum);
        $autoAmount = $autoSlots > 0 ? (int) ceil($remainingForAuto / $autoSlots) : 0;

        for ($i = 0; $i < $this->installments; $i++) {
            $schedule[$i] = $explicitSlots[$i] ?? $autoAmount;
        }

        return $schedule;
    }

    public function frequencyLabel(): string
    {
        return match ($this->frequency) {
            'weekly' => 'أسبوعي',
            'biweekly' => 'نصف شهري',
            'monthly' => 'شهري',
            'quarterly' => 'ربع سنوي',
            default => $this->frequency,
        };
    }

    public function tierLabel(): string
    {
        return match ($this->membership_tier) {
            'member' => 'أعضاء',
            'non_member' => 'غير أعضاء',
            default => 'الجميع',
        };
    }
}
