<?php

namespace App\Models;

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

class PurchaseOrder extends BaseModel
{
    use SoftDeletes;

    protected $table = 'purchase_orders';

    protected $fillable = [
        'po_number',
        'supplier_id',
        'status',
        'order_date',
        'expected_date',
        'subtotal',
        'tax',
        'total',
        'notes',
    ];

    public $timestamps = true;

    protected $casts = [
        'supplier_id'    => 'integer',
        'order_date'     => 'date',        // or 'datetime' if your DB stores time too
        'expected_date'  => 'date',
        'subtotal'       => 'decimal:2',
        'tax'            => 'decimal:2',
        'total'          => 'decimal:2',
        'created_at'     => 'datetime',
        'updated_at'     => 'datetime',
        'deleted_at'     => 'datetime',
    ];

    public function getFillable(): array
    {
        return $this->fillable;
    }

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

    public const STATUS_DRAFT    = 'draft';
    public const STATUS_ORDERED  = 'ordered';
    public const STATUS_RECEIVED = 'received';
    public const STATUS_CANCELED = 'canceled';

    public static function allowedStatuses(): array
    {
        return [
            self::STATUS_DRAFT,
            self::STATUS_ORDERED,
            self::STATUS_RECEIVED,
            self::STATUS_CANCELED,
        ];
    }

    /* ============================================================
     * Relationships
     * ============================================================
     */

    public function supplier(): BelongsTo
    {
        return $this->belongsTo(Supplier::class, 'supplier_id');
    }

    public function items(): HasMany
    {
        return $this->hasMany(PurchaseOrderItem::class, 'purchase_order_id');
    }

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

    public function scopeStatus(Builder $q, string $status): Builder
    {
        return $q->where('status', $status);
    }

    public function scopeOpen(Builder $q): Builder
    {
        return $q->whereIn('status', [self::STATUS_DRAFT, self::STATUS_ORDERED]);
    }

    /* ============================================================
     * Helpers / computed totals
     * ============================================================
     */

    /**
     * Recalculate subtotal/tax/total from items.
     * Tax rate is optional. If you store tax as absolute amount, pass null and keep existing tax.
     */
    public function recalcTotals(?float $taxRate = null): self
    {
        $subtotal = (float) $this->items()
            ->selectRaw('COALESCE(SUM(quantity * unit_cost), 0) as s')
            ->value('s');

        $tax = $taxRate === null
            ? (float) ($this->tax ?? 0)
            : round($subtotal * $taxRate, 2);

        $total = $subtotal + $tax;

        $this->subtotal = $subtotal;
        $this->tax      = $tax;
        $this->total    = $total;

        return $this;
    }

    public function markOrdered(): self
    {
        $this->status = self::STATUS_ORDERED;
        return $this;
    }

    public function markReceived(): self
    {
        $this->status = self::STATUS_RECEIVED;
        return $this;
    }

    public function markCanceled(): self
    {
        $this->status = self::STATUS_CANCELED;
        return $this;
    }

    /* ============================================================
     * Validation rules (controller/FormRequest reuse)
     * ============================================================
     */

    public static function rules(?int $id = null): array
    {
        // Mirrors CI: unique purchase_orders.po_number except current id.
        return [
            'po_number'   => ['required', 'string', 'max:60', 'unique:purchase_orders,po_number,' . ($id ?? 'NULL') . ',id'],
            'supplier_id' => ['required', 'integer', 'min:1', 'exists:suppliers,id'],
            'status'      => ['nullable', 'string', 'in:' . implode(',', self::allowedStatuses())],

            'order_date'     => ['nullable', 'date'],
            'expected_date'  => ['nullable', 'date', 'after_or_equal:order_date'],
            'subtotal'       => ['nullable', 'numeric', 'min:0'],
            'tax'            => ['nullable', 'numeric', 'min:0'],
            'total'          => ['nullable', 'numeric', 'min:0'],
            'notes'          => ['nullable', 'string', 'max:5000'],
        ];
    }
}
