<?php
declare(strict_types=1);

namespace App\Modules\Spouses\Models;

use App\Core\Model;
use App\Core\App;
use App\Modules\Rules\Services\RuleEngine;

class Spouse extends Model
{
    protected static string $table = 'spouses';
    protected static string $primaryKey = 'id';
    protected static bool $timestamps = true;
    protected static bool $softDelete = true;
    protected static bool $dispatchEvents = true;

    protected static array $fillable = [
        'member_id', 'spouse_order', 'full_name_ar', 'full_name_en',
        'national_id', 'passport_number', 'date_of_birth',
        'age_years', 'age_months', 'gender', 'nationality', 'religion',
        'qualification_id', 'occupation', 'work_address', 'work_phone', 'mobile',
        'marriage_date', 'join_date', 'classification', 'addition_fee',
        'fee_breakdown_json', 'fee_receipt_number', 'status', 'photo_path',
    ];

    public static function getForMember(int $memberId): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT * FROM spouses WHERE member_id = ? AND is_archived = 0 ORDER BY spouse_order ASC",
            [$memberId]
        );
    }

    public static function countActiveForMember(int $memberId): int
    {
        $db = App::getInstance()->db();
        $row = $db->selectOne(
            "SELECT COUNT(*) as cnt FROM spouses WHERE member_id = ? AND is_archived = 0",
            [$memberId]
        );
        return (int) ($row['cnt'] ?? 0);
    }

    public static function getNextOrder(int $memberId): int
    {
        return self::countActiveForMember($memberId) + 1;
    }

    public static function nidExistsElsewhere(string $nid, ?int $excludeSpouseId = null): ?array
    {
        $db = App::getInstance()->db();

        $memberDup = $db->selectOne(
            "SELECT id, full_name_ar, membership_number FROM members WHERE national_id = ? AND is_archived = 0",
            [$nid]
        );
        if ($memberDup) return ['type' => 'member', 'data' => $memberDup];

        $sql = "SELECT s.id, s.full_name_ar, m.membership_number FROM spouses s JOIN members m ON m.id = s.member_id WHERE s.national_id = ? AND s.is_archived = 0";
        $params = [$nid];
        if ($excludeSpouseId) {
            $sql .= " AND s.id != ?";
            $params[] = $excludeSpouseId;
        }
        $spouseDup = $db->selectOne($sql, $params);
        if ($spouseDup) return ['type' => 'spouse', 'data' => $spouseDup];

        $childDup = $db->selectOne(
            "SELECT c.id, c.full_name_ar, m.membership_number FROM children c JOIN members m ON m.id = c.member_id WHERE c.national_id = ? AND c.is_archived = 0",
            [$nid]
        );
        if ($childDup) return ['type' => 'child', 'data' => $childDup];

        return null;
    }

    public function getQualificationName(): string
    {
        if (!$this->qualification_id) return '—';
        $db = App::getInstance()->db();
        $row = $db->selectOne("SELECT name_ar FROM qualifications WHERE id = ?", [$this->qualification_id]);
        return $row['name_ar'] ?? '—';
    }

    public function getClassificationLabel(): string
    {
        return match ($this->classification) {
            'working'   => 'عضو عامل',
            'dependent' => 'عضو تابع',
            'seasonal'  => 'موسمي',
            default     => $this->classification ?? 'عضو عامل',
        };
    }

    public function getStatusLabel(): string
    {
        return match ($this->status) {
            'active'      => 'نشط',
            'inactive'    => 'غير نشط',
            'divorced'    => 'مطلق/ة',
            'deceased'    => 'متوفى/ة',
            'transferred' => 'منقول/ة',
            default       => $this->status ?? '',
        };
    }

    /**
     * Get the max number of spouses allowed based on member gender.
     */
    public static function getMaxSpouses(string $memberGender): int
    {
        if ($memberGender === 'female') {
            return (int) (RuleEngine::getValue('MAX_SPOUSES_FEMALE_MEMBER', 'value') ?? 1);
        }
        return (int) (RuleEngine::getValue('MAX_SPOUSES_MALE_MEMBER', 'value') ?? 4);
    }

    /**
     * Get the required spouse gender based on member gender.
     */
    public static function getRequiredSpouseGender(string $memberGender): string
    {
        return $memberGender === 'female' ? 'male' : 'female';
    }
}