<?php
declare(strict_types=1);

namespace App\Modules\Rentals\Models;

use App\Core\Model;
use App\Core\App;

class RentalContract extends Model
{
    protected static string $table = 'rental_contracts';
    protected static string $primaryKey = 'id';
    protected static bool $timestamps = true;
    protected static bool $softDelete = true;
    protected static bool $autoTrackAuthor = true;

    protected static array $fillable = [
        'contract_number',
        'entity_id',
        'facility_id',
        'activity_type',
        'start_date',
        'end_date',
        'total_units',
        'unit_rate',
        'time_tier',
        'subtotal',
        'discount_percentage',
        'discount_amount',
        'total_amount',
        'deposit_percentage',
        'deposit_amount',
        'deposit_status',
        'deposit_payment_id',
        'technical_report_submitted',
        'status',
        'approved_by',
        'approved_at',
        'terms_json',
        'notes',
    ];

    /**
     * Get all contract statuses with Arabic labels.
     */
    public static function getStatuses(): array
    {
        return [
            'draft'            => 'مسودة',
            'pending_approval' => 'بانتظار الاعتماد',
            'approved'         => 'مُعتمد',
            'active'           => 'فعال',
            'completed'        => 'مكتمل',
            'cancelled'        => 'ملغى',
            'terminated'       => 'منهي',
        ];
    }

    /**
     * Get all deposit statuses with Arabic labels.
     */
    public static function getDepositStatuses(): array
    {
        return [
            'pending'            => 'قيد التحصيل',
            'collected'          => 'محصّل',
            'partially_refunded' => 'مسترد جزئياً',
            'refunded'           => 'مسترد',
        ];
    }

    /**
     * Get the Arabic label for a status key.
     */
    public static function getStatusLabel(string $status): string
    {
        $statuses = self::getStatuses();
        return $statuses[$status] ?? $status;
    }

    /**
     * Get the badge color for a contract status.
     */
    public static function getStatusColor(string $status): string
    {
        $colors = [
            'draft'            => '#6B7280',
            'pending_approval' => '#D97706',
            'approved'         => '#7C3AED',
            'active'           => '#059669',
            'completed'        => '#0284C7',
            'cancelled'        => '#DC2626',
            'terminated'       => '#991B1B',
        ];
        return $colors[$status] ?? '#6B7280';
    }

    /**
     * Get the Arabic label for a deposit status key.
     */
    public static function getDepositStatusLabel(string $status): string
    {
        $statuses = self::getDepositStatuses();
        return $statuses[$status] ?? $status;
    }

    /**
     * Get the badge color for a deposit status.
     */
    public static function getDepositStatusColor(string $status): string
    {
        $colors = [
            'pending'            => '#D97706',
            'collected'          => '#059669',
            'partially_refunded' => '#7C3AED',
            'refunded'           => '#0284C7',
        ];
        return $colors[$status] ?? '#6B7280';
    }

    /**
     * Decode terms_json into an associative array.
     */
    public function getTerms(): array
    {
        $raw = $this->terms_json;
        if (empty($raw)) {
            return [];
        }
        $decoded = json_decode($raw, true);
        return is_array($decoded) ? $decoded : [];
    }

    /**
     * Generate a contract number in RC-YYYYMM-XXXX format.
     */
    public static function generateNumber(): string
    {
        $prefix = 'RC-' . date('Ym') . '-';
        $db = App::getInstance()->db();
        $row = $db->selectOne(
            "SELECT contract_number FROM rental_contracts WHERE contract_number LIKE ? ORDER BY id DESC LIMIT 1",
            [$prefix . '%']
        );

        $nextSeq = 1;
        if ($row) {
            $number = is_object($row) ? $row->contract_number : ($row['contract_number'] ?? '');
            $parts = explode('-', (string) $number);
            $lastSeq = (int) ($parts[2] ?? 0);
            $nextSeq = $lastSeq + 1;
        }

        return $prefix . str_pad((string) $nextSeq, 4, '0', STR_PAD_LEFT);
    }

    /**
     * Search contracts with filters and pagination.
     */
    public static function search(array $filters, int $perPage = 25, int $page = 1): array
    {
        $query = static::query();

        if (!empty($filters['q'])) {
            $search = '%' . $filters['q'] . '%';
            $query = $query->whereRaw(
                '(`contract_number` LIKE ? OR `notes` LIKE ?)',
                [$search, $search]
            );
        }

        if (!empty($filters['entity_id'])) {
            $query = $query->where('entity_id', '=', (int) $filters['entity_id']);
        }

        if (!empty($filters['facility_id'])) {
            $query = $query->where('facility_id', '=', (int) $filters['facility_id']);
        }

        if (!empty($filters['status'])) {
            $query = $query->where('status', '=', $filters['status']);
        }

        $query = $query->orderBy('created_at', 'DESC');

        return $query->paginate($perPage, $page);
    }

    /**
     * Get all contracts for a specific entity.
     */
    public static function getForEntity(int $entityId): array
    {
        return static::query()
            ->where('entity_id', '=', $entityId)
            ->orderBy('created_at', 'DESC')
            ->get();
    }
}
