<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use App\Models\BaseModel;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Refund extends BaseModel
{
    protected $table = 'refunds';

    protected $fillable = [
        'parent_id',
        'school_year',
        'invoice_id',
        'refund_amount',
        'requested_at',
        'approved_at',
        'refunded_at',
        'status',
        'reason',
        'refund_paid_amount',
        'request',
        'note',
        'approved_by',
        'updated_by',
        'refund_method',
        'check_nbr',
        'check_file',
        'created_at',
        'updated_at',
        'semester',
    ];

    public $timestamps = true;

    protected $casts = [
        'parent_id'          => 'integer',
        'invoice_id'         => 'integer',
        'approved_by'        => 'integer',
        'updated_by'         => 'integer',

        'refund_amount'      => 'decimal:2',
        'refund_paid_amount' => 'decimal:2',

        'requested_at'       => 'datetime',
        'approved_at'        => 'datetime',
        'refunded_at'        => 'datetime',

        'created_at'         => 'datetime',
        'updated_at'         => 'datetime',
    ];

    /* ============================================================
     * Status (enum-like)
     * ============================================================
     */

    public const STATUS_PENDING = 'Pending';
    public const STATUS_APPROVED = 'Approved';
    public const STATUS_PARTIAL = 'Partial';
    public const STATUS_PAID = 'Paid';
    public const STATUS_REJECTED = 'Rejected';
    public const STATUS_CANCELED = 'Canceled';

    public static function paidOutStatuses(): array
    {
        // matches your CI whereIn(['Partial','Paid'])
        return [self::STATUS_PARTIAL, self::STATUS_PAID];
    }

    /* ============================================================
     * Relationships (optional)
     * ============================================================
     */

    public function parent(): BelongsTo
    {
        return $this->belongsTo(ParentModel::class, 'parent_id'); // rename to your real model, e.g. ParentUser/Guardian/Customer
    }

    public function invoice(): BelongsTo
    {
        return $this->belongsTo(Invoice::class, 'invoice_id');
    }

    /* ============================================================
     * Scopes
     * ============================================================
     */

    public function scopeForParent(Builder $q, int $parentId): Builder
    {
        return $q->where('parent_id', $parentId);
    }

    public function scopeForSchoolYear(Builder $q, string $schoolYear): Builder
    {
        return $q->where('school_year', $schoolYear);
    }

    public function scopePaidOut(Builder $q): Builder
    {
        return $q->whereIn('status', self::paidOutStatuses());
    }

    /* ============================================================
     * Business: totals
     * ============================================================
     */

    /**
     * Total paid-out refunds for a parent in a specific school year (Partial + Paid).
     * Mirrors the CI behavior and returns 0.00 if none.
     */
    public static function totalApprovedPaidOutForParentAndYear(int $parentId, string $schoolYear): float
    {
        $sum = static::query()
            ->forParent($parentId)
            ->forSchoolYear($schoolYear)
            ->paidOut()
            ->sum('refund_paid_amount');

        return (float) $sum;
    }

    /**
     * Instance-style method if you want to keep a similar calling style to CI.
     */
    public function getTotalApprovedRefundByParentIdAndSchoolYear(int $parentId, string $schoolYear): float
    {
        return static::totalApprovedPaidOutForParentAndYear($parentId, $schoolYear);
    }

    /* ============================================================
     * Validation rules (optional helper for controllers/FormRequests)
     * ============================================================
     */

    public static function rules(?int $id = null): array
    {
        return [
            'parent_id'          => ['required', 'integer', 'min:1', 'exists:parents,id'], // adjust table name
            'school_year'        => ['required', 'string', 'max:20'],
            'invoice_id'         => ['nullable', 'integer', 'exists:invoices,id'],

            'refund_amount'      => ['required', 'numeric', 'min:0'],
            'refund_paid_amount' => ['nullable', 'numeric', 'min:0'],

            'requested_at'       => ['nullable', 'date'],
            'approved_at'        => ['nullable', 'date', 'after_or_equal:requested_at'],
            'refunded_at'        => ['nullable', 'date', 'after_or_equal:approved_at'],

            'status'             => ['required', 'string', 'in:' . implode(',', [
                self::STATUS_PENDING,
                self::STATUS_APPROVED,
                self::STATUS_PARTIAL,
                self::STATUS_PAID,
                self::STATUS_REJECTED,
                self::STATUS_CANCELED,
            ])],

            'reason'        => ['nullable', 'string', 'max:2000'],
            'request'       => ['nullable', 'string'],
            'note'          => ['nullable', 'string', 'max:5000'],
            'semester'      => ['nullable', 'string', 'max:20'],

            'approved_by'   => ['nullable', 'integer'],
            'updated_by'    => ['nullable', 'integer'],

            'refund_method' => ['nullable', 'string', 'max:50'], // cash/check/cc/etc.
            'check_nbr'     => ['nullable', 'string', 'max:80'],
            'check_file'    => ['nullable', 'string', 'max:255'],
        ];
    }
}