<?php

namespace App\Models\Traits;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;

/**
 * Approval Workflow Trait
 *
 * Provides approval-related scopes and methods for models
 * that go through approval workflows (invoices, orders, etc.)
 */
trait HasApproval
{
    /**
     * Status constants
     */
    public const STATUS_PENDING = 'pending';
    public const STATUS_APPROVED = 'approved';
    public const STATUS_REJECTED = 'rejected';

    /**
     * Boot the trait
     */
    public static function bootHasApproval(): void
    {
        // Can add model events here if needed
    }

    /**
     * Get all valid statuses
     */
    public static function getStatuses(): array
    {
        return [
            self::STATUS_PENDING,
            self::STATUS_APPROVED,
            self::STATUS_REJECTED,
        ];
    }

    /**
     * Scope: Pending approval
     */
    public function scopePendingApproval(Builder $query): Builder
    {
        $column = $this->getApprovalStatusColumn();
        return $query->where($column, self::STATUS_PENDING);
    }

    /**
     * Scope: Approved items
     */
    public function scopeApprovedOnly(Builder $query): Builder
    {
        $column = $this->getApprovalStatusColumn();
        return $query->where($column, self::STATUS_APPROVED);
    }

    /**
     * Scope: Rejected items
     */
    public function scopeRejectedOnly(Builder $query): Builder
    {
        $column = $this->getApprovalStatusColumn();
        return $query->where($column, self::STATUS_REJECTED);
    }

    /**
     * Check if pending
     */
    public function isPending(): bool
    {
        $column = $this->getApprovalStatusColumn();
        return $this->{$column} === self::STATUS_PENDING;
    }

    /**
     * Check if approved
     */
    public function isApproved(): bool
    {
        $column = $this->getApprovalStatusColumn();
        return $this->{$column} === self::STATUS_APPROVED;
    }

    /**
     * Check if rejected
     */
    public function isRejected(): bool
    {
        $column = $this->getApprovalStatusColumn();
        return $this->{$column} === self::STATUS_REJECTED;
    }

    /**
     * Approve the model
     */
    public function approve(?string $remarks = null): bool
    {
        $statusColumn = $this->getApprovalStatusColumn();

        $data = [
            $statusColumn => self::STATUS_APPROVED,
            'approved_by' => Auth::id(),
            'approved_at' => now(),
        ];

        if ($remarks !== null && $this->hasApprovalRemarks()) {
            $data['approval_remarks'] = $remarks;
        }

        return $this->update($data);
    }

    /**
     * Reject the model
     */
    public function reject(?string $remarks = null): bool
    {
        $statusColumn = $this->getApprovalStatusColumn();

        $data = [
            $statusColumn => self::STATUS_REJECTED,
            'approved_by' => Auth::id(),
            'approved_at' => now(),
        ];

        if ($remarks !== null && $this->hasApprovalRemarks()) {
            $data['approval_remarks'] = $remarks;
        }

        return $this->update($data);
    }

    /**
     * Get approval status column (override in model if different)
     */
    protected function getApprovalStatusColumn(): string
    {
        return property_exists($this, 'approvalStatusColumn')
            ? $this->approvalStatusColumn
            : 'status';
    }

    /**
     * Check if model has approval remarks column
     */
    protected function hasApprovalRemarks(): bool
    {
        return in_array('approval_remarks', $this->fillable ?? []);
    }

    /**
     * Get approver relationship
     */
    public function approver()
    {
        return $this->belongsTo(\App\Models\User::class, 'approved_by');
    }
}
