<?php
declare(strict_types=1);

namespace App\Modules\Transfers\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Core\EventBus;
use App\Modules\Transfers\Models\TransferRequest;
use App\Modules\Transfers\Services\SeparationFeeCalculator;
use App\Modules\Transfers\Services\TransferProcessor;
use App\Modules\Payments\Services\PaymentService;
use App\Modules\Cashier\Services\PaymentRequestService;
use App\Modules\Forms\Services\FormBridge;
use App\Modules\Rules\Services\RuleEngine;
use App\Modules\Members\Services\NationalIdParser;

class TransferController extends Controller
{
    public function index(Request $request): Response
    {
        $filters = [
            'search'        => trim((string) $request->get('q', '')),
            'status'        => $request->get('status', ''),
            'transfer_type' => $request->get('transfer_type', ''),
        ];
        $page = max(1, (int) $request->get('page', 1));
        $result = TransferRequest::search($filters, 25, $page);

        return $this->view('Transfers.Views.index', [
            'rows'       => $result['data'],
            'pagination' => $result['pagination'],
            'filters'    => $filters,
        ]);
    }

    public function create(Request $request, string $memberId): Response
    {
        $db = App::getInstance()->db();
        $member = $db->selectOne("SELECT * FROM members WHERE id = ? AND is_archived = 0", [(int) $memberId]);
        if (!$member) return $this->redirect('/members')->withError('العضو غير موجود');

        $children = $db->select("SELECT * FROM children WHERE member_id = ? AND is_archived = 0 AND status = 'active'", [(int) $memberId]);
        $spouses = $db->select("SELECT * FROM spouses WHERE member_id = ? AND is_archived = 0 AND status = 'active'", [(int) $memberId]);
        $qualifications = $db->select("SELECT id, code, name_ar FROM qualifications WHERE is_active = 1 ORDER BY sort_order");

        return $this->view('Transfers.Views.create', [
            'member'         => $member,
            'children'       => $children,
            'spouses'        => $spouses,
            'qualifications' => $qualifications,
        ]);
    }

    public function store(Request $request, string $memberId): Response
    {
        $db = App::getInstance()->db();
        $member = $db->selectOne("SELECT * FROM members WHERE id = ? AND is_archived = 0", [(int) $memberId]);
        if (!$member) return $this->redirect('/members')->withError('العضو غير موجود');

        $transferType = trim($request->post('transfer_type', ''));
        $childId = $request->post('child_id') ? (int) $request->post('child_id') : null;
        $spouseId = $request->post('spouse_id') ? (int) $request->post('spouse_id') : null;
        $notes = trim($request->post('notes', ''));
        $paymentMethod = trim($request->post('payment_method', 'cash'));
        $formNumber = trim((string) $request->post('form_number', ''));

        $validTypes = ['child_separation', 'child_mandatory_25', 'sports_conversion', 'cross_branch', 'full_transfer'];
        if (!in_array($transferType, $validTypes)) {
            return $this->redirect("/transfers/create/{$memberId}")->withError('نوع التحويل غير صالح');
        }

        if (in_array($transferType, ['child_separation', 'child_mandatory_25']) && !$childId) {
            return $this->redirect("/transfers/create/{$memberId}")->withError('يجب اختيار الابن/الابنة');
        }

        // Age validation: male dependents under separation age can only separate if employed+graduated
        // Females are separated based on marriage date, not age
        if ($transferType === 'child_separation' && $childId) {
            $child = $db->selectOne("SELECT * FROM children WHERE id = ? AND is_archived = 0", [$childId]);
            if ($child && ($child['gender'] ?? 'male') === 'male' && !empty($child['date_of_birth'])) {
                $dob = new \DateTime($child['date_of_birth']);
                $now = new \DateTime();
                $age = (int) $now->diff($dob)->y;
                $separationAge = (int) (RuleEngine::getValue('CHILD_MANDATORY_SEPARATION_AGE', 'value') ?? 25);
                if ($age < $separationAge) {
                    $isEmployedPost = $request->post('is_employed', '');
                    $graduationDate = trim($request->post('graduation_date', '')) ?: null;
                    if ($isEmployedPost === '' || !(bool)(int)$isEmployedPost || !$graduationDate) {
                        return $this->redirect("/transfers/create/{$memberId}")->withError(
                            'لا يمكن فصل الملحق تحت سن ' . $separationAge . ' سنة إلا إذا كان متخرجاً وموظفاً بأجر. العمر الحالي: ' . $age . ' سنة.'
                        );
                    }
                }
            }
        }

        // Fetch child record if needed (may have been loaded in age-validation block above)
        $child = isset($child) ? $child : ($childId ? $db->selectOne("SELECT * FROM children WHERE id = ?", [$childId]) : null);

        // فصل أبناء: read employment fields and compute effective transfer date
        $isEmployed = null;
        $graduationDate = null;
        $workDate = null;
        $dateTurned25 = null;
        $effectiveTransferDate = null;
        $marriageDate = null;

        if ($transferType === 'child_separation' && $child) {
            $childGender = $child['gender'] ?? 'male';
            $memberRecord = $db->selectOne("SELECT created_at, activated_at FROM members WHERE id = ?", [(int) $memberId]);
            $membershipStart = $memberRecord['activated_at'] ?? $memberRecord['created_at'] ?? null;
            $membershipStartDate = $membershipStart ? substr($membershipStart, 0, 10) : null;

            if ($childGender === 'female') {
                // Female path: effective date = marriage_date only
                $marriageDate = trim($request->post('marriage_date', '')) ?: null;
                if (!$marriageDate) {
                    return $this->redirect("/transfers/create/{$memberId}")->withError('يجب إدخال تاريخ الزواج لفصل الإناث');
                }
                if ($membershipStartDate && $marriageDate < $membershipStartDate) {
                    return $this->redirect("/transfers/create/{$memberId}")->withError(
                        'تاريخ الزواج (' . $marriageDate . ') لا يمكن أن يسبق تاريخ إنشاء العضوية (' . $membershipStartDate . '). يرجى مراجعة البيانات.'
                    );
                }
                $effectiveTransferDate = $marriageDate;
            } else {
                // Male path: work + graduation + date_turned_25
                $isEmployedPost = $request->post('is_employed', '');
                if ($isEmployedPost === '') {
                    return $this->redirect("/transfers/create/{$memberId}")->withError('يجب تحديد حالة التوظيف');
                }
                $isEmployed = (bool) (int) $isEmployedPost;

                $graduationDate = trim($request->post('graduation_date', '')) ?: null;

                if ($isEmployed) {
                    $workDate = trim($request->post('work_date', '')) ?: null;
                    if (!$workDate) {
                        return $this->redirect("/transfers/create/{$memberId}")->withError('يجب إدخال تاريخ مباشرة العمل عند اختيار موظف');
                    }
                    if (!$graduationDate) {
                        return $this->redirect("/transfers/create/{$memberId}")->withError('يجب إدخال تاريخ التخرج عند اختيار موظف');
                    }
                }

                $date25Override = trim($request->post('date_turned_25', '')) ?: null;

                if (empty($child['date_of_birth'])) {
                    return $this->redirect("/transfers/create/{$memberId}")->withError('لا يوجد تاريخ ميلاد للابن — لا يمكن احتساب تاريخ الفصل');
                }

                $dates = SeparationFeeCalculator::computeChildSeparationDates(
                    $child['date_of_birth'],
                    $isEmployed,
                    $workDate,
                    $date25Override,
                    $graduationDate
                );
                $dateTurned25 = $dates['date_turned_25'];
                $effectiveTransferDate = $dates['effective_transfer_date'];

                if ($membershipStartDate && $effectiveTransferDate && $effectiveTransferDate < $membershipStartDate) {
                    return $this->redirect("/transfers/create/{$memberId}")->withError(
                        'تاريخ الفصل المحسوب (' . $effectiveTransferDate . ') لا يمكن أن يسبق تاريخ إنشاء العضوية (' . $membershipStartDate . '). يرجى مراجعة البيانات.'
                    );
                }
            }
        }

        // Read dependent counts for new membership (child_separation)
        $depSpouses = 0;
        $depChildren = 0;
        $depTemps = 0;
        if ($transferType === 'child_separation') {
            $depSpouses = (int) $request->post('dep_spouses_count', 0);
            $depChildren = (int) $request->post('dep_children_count', 0);
            $depTemps = (int) $request->post('dep_temps_count', 0);
        }

        // Calculate fees
        $qualCode = trim($request->post('qualification_code', '')) ?: null;

        if ($transferType === 'child_separation' && !$qualCode) {
            return $this->redirect("/transfers/create/{$memberId}")->withError('يجب اختيار المؤهل لحساب رسوم الفصل');
        }

        if ($transferType === 'child_separation' && $child && $effectiveTransferDate) {
            // Count foreign spouses from submitted dependent data
            $foreignSpouseCount = 0;
            $rawSpousesForCount = $request->post('dep_spouses', []);
            foreach ($rawSpousesForCount as $sp) {
                if (!empty($sp['full_name_ar']) && ($sp['nationality'] ?? 'مصري') === 'أجنبي') {
                    $foreignSpouseCount++;
                }
            }

            $feeCalc = SeparationFeeCalculator::calculateForChildSeparation(
                (int) $memberId,
                (int) $childId,
                (bool) $isEmployed,
                $workDate,
                $effectiveTransferDate,
                $qualCode,
                $depSpouses,
                $depChildren,
                $depTemps,
                $foreignSpouseCount
            );
        } else {
            $feeCalc = SeparationFeeCalculator::calculate((int) $memberId, $childId, $qualCode);
        }

        if (!($feeCalc['success'] ?? false)) {
            return $this->redirect("/transfers/create/{$memberId}")->withError($feeCalc['error'] ?? 'خطأ في حساب الرسوم');
        }

        // Companion validation: check if new owner brings extra dependents
        $targetSpousesCount = (int) $request->post('target_spouses_count', 0);
        $targetChildrenCount = (int) $request->post('target_children_count', 0);
        $targetChildrenAges = array_map('intval', $request->post('target_children_ages', []));
        $companionSurcharge = '0.00';
        $companionBreakdown = null;
        $sourceCompanionsCount = null;
        $targetCompanionsCount = null;

        if ($targetSpousesCount > 0 || $targetChildrenCount > 0) {
            $surchargeResult = SeparationFeeCalculator::calculateCompanionSurcharge(
                (int) $memberId,
                $targetSpousesCount,
                $targetChildrenCount,
                $targetChildrenAges
            );
            $companionSurcharge = $surchargeResult['surcharge'];
            $sourceCompanionsCount = $surchargeResult['source_count'];
            $targetCompanionsCount = $surchargeResult['target_count'];
            if (!empty($surchargeResult['breakdown'])) {
                $companionBreakdown = json_encode($surchargeResult['breakdown'], JSON_UNESCAPED_UNICODE);
            }
        }

        $totalWithSurcharge = bcadd($feeCalc['total_fee'], $companionSurcharge, 2);

        // For full_transfer: store recipient data in notes JSON
        $recipientData = null;
        if ($transferType === 'full_transfer') {
            $recipientFields = ['full_name_ar', 'full_name_en', 'national_id', 'date_of_birth', 'gender', 'nationality', 'qualification_id', 'phone_mobile', 'marital_status', 'religion', 'phone_home', 'email', 'emergency_name', 'emergency_phone', 'residence_address', 'area', 'governorate', 'occupation', 'job_title'];
            $recipientData = [];
            foreach ($recipientFields as $field) {
                $val = trim($request->post('recipient_' . $field, ''));
                if ($val !== '') {
                    $recipientData[$field] = $val;
                }
            }
            if (empty($recipientData['full_name_ar']) || empty($recipientData['national_id'])) {
                return $this->redirect("/transfers/create/{$memberId}")->withError('بيانات المستلم مطلوبة (الاسم والرقم القومي)');
            }
            $rNid = $recipientData['national_id'] ?? '';
            if ($rNid !== '' && strlen($rNid) === 14) {
                $parsed = NationalIdParser::parse($rNid);
                if ($parsed['is_valid']) {
                    $recipientData['date_of_birth'] = $parsed['dob'];
                    $recipientData['gender'] = $parsed['gender'];
                }
                $activeConflict = $db->selectOne(
                    "SELECT id, full_name_ar FROM members WHERE national_id = ? AND status = 'active' AND is_archived = 0",
                    [$rNid]
                );
                if ($activeConflict) {
                    return $this->redirect("/transfers/create/{$memberId}")->withError(
                        'يوجد عضو فعّال بنفس الرقم القومي للمستلم: ' . $activeConflict['full_name_ar'] . ' (#' . $activeConflict['id'] . ')'
                    );
                }
            }
        }

        $employee = App::getInstance()->currentEmployee();

        // Build notes JSON
        $notesJson = null;
        if ($transferType === 'full_transfer' && $recipientData) {
            $notesPayload = ['recipient_data' => $recipientData];
            if ($notes) $notesPayload['user_notes'] = $notes;
            $notesJson = json_encode($notesPayload, JSON_UNESCAPED_UNICODE);
        } elseif ($transferType === 'child_separation' && ($depSpouses > 0 || $depChildren > 0 || $depTemps > 0)) {
            $rawSpouses = $request->post('dep_spouses', []);
            $rawChildren = $request->post('dep_children', []);
            $rawTemps = $request->post('dep_temps', []);

            // Validate spouses: min age, required fields
            $spouseMinAge = (int) (RuleEngine::getValue('SPOUSE_MIN_AGE', 'value') ?? 21);
            foreach ($rawSpouses as $idx => $sp) {
                if (empty($sp['full_name_ar'])) continue;
                $spDob = $sp['date_of_birth'] ?? null;
                if (!$spDob) {
                    $spNid = $sp['national_id'] ?? '';
                    if (strlen($spNid) === 14) {
                        $parsed = NationalIdParser::parse($spNid);
                        if ($parsed['is_valid']) $spDob = $parsed['dob'];
                    }
                }
                if ($spDob) {
                    $age = (int) date_diff(date_create($spDob), date_create('today'))->y;
                    if ($age < $spouseMinAge) {
                        return $this->redirect("/transfers/create/{$memberId}")
                            ->withError('الزوج/ة رقم ' . ($idx + 1) . ' يجب أن يكون عمره ' . $spouseMinAge . ' سنة على الأقل');
                    }
                }
                if (empty($sp['marriage_date'])) {
                    return $this->redirect("/transfers/create/{$memberId}")
                        ->withError('يجب إدخال تاريخ الزواج للزوج/ة رقم ' . ($idx + 1));
                }
            }

            $dependentsData = [
                'spouses' => $rawSpouses,
                'children' => $rawChildren,
                'temporary_members' => $rawTemps,
            ];
            $notesPayload = ['dependents_data' => $dependentsData];
            if ($notes) $notesPayload['user_notes'] = $notes;
            $notesJson = json_encode($notesPayload, JSON_UNESCAPED_UNICODE);
        } else {
            $notesJson = $notes ?: null;
        }

        $createData = [
            'source_member_id'             => (int) $memberId,
            'transfer_type'                => $transferType,
            'child_id'                     => $childId,
            'spouse_id'                    => $spouseId,
            'source_membership_number'     => $member['membership_number'],
            'new_membership_value'         => $feeCalc['new_membership_value'] ?? $feeCalc['subscription_price'] ?? '0.00',
            'form_number'                  => $formNumber !== '' ? $formNumber : null,
            'source_companions_count'      => $sourceCompanionsCount,
            'target_companions_count'      => $targetCompanionsCount,
            'companion_surcharge'          => $companionSurcharge,
            'companion_surcharge_breakdown'=> $companionBreakdown,
            'years_since_acquisition'      => $feeCalc['years_since_acquisition'],
            'qualification_code'           => $feeCalc['qualification_code'],
            'fee_percentage'               => $feeCalc['fee_percentage'],
            'separation_fee'               => $feeCalc['separation_fee'],
            'form_fee'                     => $feeCalc['form_fee'],
            'annual_subscription_fee'      => $feeCalc['annual_subscription_fee'],
            'foreign_spouse_fee'           => $feeCalc['foreign_spouse_fee'] ?? '0.00',
            'total_fee'                    => $totalWithSurcharge,
            'status'                       => 'requested',
            'notes'                        => $notesJson,
            'is_employed'                  => $isEmployed !== null ? ($isEmployed ? 1 : 0) : null,
            'graduation_date'              => $graduationDate,
            'work_date'                    => $workDate,
            'date_turned_25'               => $dateTurned25,
            'effective_transfer_date'      => $effectiveTransferDate,
        ];

        if ($marriageDate !== null) {
            $createData['marriage_date'] = $marriageDate;
        }
        if ($depSpouses > 0) {
            $createData['target_spouses_count'] = $depSpouses;
        }
        if ($depChildren > 0) {
            $createData['target_children_count'] = $depChildren;
        }
        if ($depTemps > 0) {
            $createData['target_temps_count'] = $depTemps;
        }

        $transferReq = TransferRequest::create($createData);

        if (FormBridge::exists('TRANSFER_SEPARATION')) {
            FormBridge::submit('TRANSFER_SEPARATION', $request->all(), (int) $memberId, 'طلب فصل/تحويل');
        }

        EventBus::dispatch('transfer.requested', [
            'transfer_id' => (int) $transferReq->id,
            'member_id'   => (int) $memberId,
            'type'        => $transferType,
        ]);

        return $this->redirect("/transfers/{$transferReq->id}")->withSuccess(
            'تم تقديم طلب الفصل — الإجمالي: ' . money($totalWithSurcharge) . ' — في انتظار اعتماد مجلس الإدارة'
        );
    }

    public function show(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $transfer = $db->selectOne(
            "SELECT tr.*, m.full_name_ar as source_name, m.membership_number as source_number,
                    tm.full_name_ar as target_name, tm.membership_number as target_number,
                    c.full_name_ar as child_name, s.full_name_ar as spouse_name,
                    e.full_name_ar as approved_by_name
             FROM transfer_requests tr
             JOIN members m ON m.id = tr.source_member_id
             LEFT JOIN members tm ON tm.id = tr.target_member_id
             LEFT JOIN children c ON c.id = tr.child_id
             LEFT JOIN spouses s ON s.id = tr.spouse_id
             LEFT JOIN employees e ON e.id = tr.approved_by
             WHERE tr.id = ?",
            [(int) $id]
        );
        if (!$transfer) return $this->redirect('/transfers')->withError('طلب التحويل غير موجود');

        return $this->view('Transfers.Views.show', ['transfer' => $transfer]);
    }

    public function pay(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $transfer = $db->selectOne("SELECT * FROM transfer_requests WHERE id = ?", [(int) $id]);
        if (!$transfer) return $this->redirect('/transfers')->withError('الطلب غير موجود');
        if ($transfer['status'] !== 'approved') {
            return $this->redirect("/transfers/{$id}")->withError('يجب اعتماد الطلب أولاً قبل الدفع');
        }

        $amount = $transfer['total_fee'] ?? '0.00';
        if (bccomp((string) $amount, '0', 2) <= 0) {
            return $this->redirect("/transfers/{$id}")->withError('لا توجد رسوم مطلوبة');
        }

        $result = PaymentService::processPayment([
            'member_id'           => (int) $transfer['source_member_id'],
            'amount'              => $amount,
            'payment_type'        => 'separation_fee',
            'payment_method'      => $request->post('payment_method', 'cash'),
            'related_entity_type' => 'transfer_requests',
            'related_entity_id'   => (int) $id,
            'description'         => 'رسوم تحويل/فصل — طلب #' . $id,
        ]);

        if (!$result['success']) {
            return $this->redirect("/transfers/{$id}")->withError($result['error']);
        }

        $db->update('transfer_requests', [
            'status'     => 'fee_paid',
            'updated_at' => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        EventBus::dispatch('transfer.fee_paid', ['transfer_id' => (int) $id, 'payment_id' => $result['payment_id']]);

        return $this->redirect("/transfers/{$id}")->withSuccess('تم دفع رسوم التحويل — إيصال: ' . $result['receipt_number']);
    }

    public function approve(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $transfer = $db->selectOne("SELECT * FROM transfer_requests WHERE id = ? AND status = 'requested'", [(int) $id]);
        if (!$transfer) return $this->redirect('/transfers')->withError('الطلب غير موجود أو تم التعامل معه');

        $employee = App::getInstance()->currentEmployee();
        $boardNotes = trim($request->post('board_decision_notes', ''));

        $db->update('transfer_requests', [
            'status'               => 'approved',
            'approved_by'          => $employee ? (int) $employee->id : null,
            'approved_at'          => date('Y-m-d H:i:s'),
            'board_decision_notes' => $boardNotes ?: null,
            'updated_at'           => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        EventBus::dispatch('transfer.approved', ['transfer_id' => (int) $id]);

        // Send payment to cashier queue after approval
        $amount = $transfer['total_fee'] ?? '0.00';
        if (bccomp((string) $amount, '0', 2) > 0) {
            $child = $transfer['child_id'] ? $db->selectOne("SELECT full_name_ar FROM children WHERE id = ?", [(int) $transfer['child_id']]) : null;
            $childName = $child['full_name_ar'] ?? '';

            $feeBreakdown = [];
            if (bccomp($transfer['separation_fee'] ?? '0', '0', 2) > 0) {
                $feeBreakdown[] = 'رسوم الفصل: ' . money($transfer['separation_fee']);
            }
            if (bccomp($transfer['form_fee'] ?? '0', '0', 2) > 0) {
                $feeBreakdown[] = 'رسوم الاستمارة: ' . money($transfer['form_fee']);
            }
            if (bccomp($transfer['annual_subscription_fee'] ?? '0', '0', 2) > 0) {
                $feeBreakdown[] = 'الاشتراك السنوي: ' . money($transfer['annual_subscription_fee']);
            }
            if (bccomp($transfer['companion_surcharge'] ?? '0', '0', 2) > 0) {
                $feeBreakdown[] = 'فرق مرافقين: ' . money($transfer['companion_surcharge']);
            }
            $feeBreakdown[] = '💵 الإجمالي: ' . money($amount);

            PaymentRequestService::createRequest([
                'member_id'           => (int) $transfer['source_member_id'],
                'amount'              => $amount,
                'payment_type'        => 'separation_fee',
                'related_entity_type' => 'transfer_requests',
                'related_entity_id'   => (int) $id,
                'description_ar'      => $childName
                    ? 'رسوم فصل — ' . $childName . ' — طلب #' . $id
                    : 'رسوم تحويل/فصل — طلب #' . $id,
                'notes'               => json_encode(['child_name' => $childName, 'fee_breakdown' => $feeBreakdown], JSON_UNESCAPED_UNICODE),
            ]);
        }

        return $this->redirect("/transfers/{$id}")->withSuccess('تمت الموافقة وإرسال طلب الدفع للخزينة — المبلغ: ' . money($amount));
    }

    public function reject(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $transfer = $db->selectOne("SELECT * FROM transfer_requests WHERE id = ? AND status = 'requested'", [(int) $id]);
        if (!$transfer) return $this->redirect('/transfers')->withError('الطلب غير موجود');

        $reason = trim($request->post('reject_reason', ''));
        $employee = App::getInstance()->currentEmployee();

        $db->update('transfer_requests', [
            'status'               => 'rejected',
            'board_decision_notes' => $reason ?: 'مرفوض',
            'approved_by'          => $employee ? (int) $employee->id : null,
            'approved_at'          => date('Y-m-d H:i:s'),
            'updated_at'           => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        return $this->redirect('/transfers')->withSuccess('تم رفض طلب التحويل');
    }

    public function fillForm(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $transfer = $db->selectOne("SELECT * FROM transfer_requests WHERE id = ?", [(int) $id]);
        if (!$transfer || $transfer['status'] !== 'pending_form_fill') {
            return $this->redirect("/transfers/{$id}")->withError('لا يمكن ملء الاستمارة في هذه المرحلة');
        }

        $child = $transfer['child_id'] ? $db->selectOne("SELECT * FROM children WHERE id = ?", [(int) $transfer['child_id']]) : null;
        $sourceMember = $db->selectOne("SELECT * FROM members WHERE id = ?", [(int) $transfer['source_member_id']]);

        // Resolve the locked qualification from the transfer request
        $lockedQualification = null;
        if (!empty($transfer['qualification_code'])) {
            $lockedQualification = $db->selectOne(
                "SELECT id, code, name_ar FROM qualifications WHERE code = ? AND is_active = 1",
                [$transfer['qualification_code']]
            );
        }

        return $this->view('Transfers.Views.form_fill', [
            'transfer'            => $transfer,
            'child'               => $child,
            'sourceMember'        => $sourceMember,
            'lockedQualification' => $lockedQualification,
            'qualifications'      => $db->select("SELECT id, name_ar FROM qualifications WHERE is_active = 1 ORDER BY sort_order"),
        ]);
    }

    public function saveFillForm(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $transfer = $db->selectOne("SELECT * FROM transfer_requests WHERE id = ?", [(int) $id]);
        if (!$transfer || $transfer['status'] !== 'pending_form_fill') {
            return $this->redirect("/transfers/{$id}")->withError('لا يمكن ملء الاستمارة في هذه المرحلة');
        }

        $data = $request->all();
        unset($data['_csrf_token']);

        // Force qualification from transfer request (locked at fee calculation time)
        if (!empty($transfer['qualification_code'])) {
            $lockedQual = $db->selectOne(
                "SELECT id FROM qualifications WHERE code = ? AND is_active = 1",
                [$transfer['qualification_code']]
            );
            if ($lockedQual) {
                $data['qualification_id'] = (string) $lockedQual['id'];
            }
        }

        $nid = trim((string) ($data['national_id'] ?? ''));
        if ($nid !== '' && strlen($nid) === 14) {
            $parsed = NationalIdParser::parse($nid);
            if ($parsed['is_valid']) {
                $data['date_of_birth'] = $parsed['dob'];
                $data['gender'] = $parsed['gender'];
            }
        }

        $requiredFields = ['full_name_ar', 'national_id', 'phone_mobile', 'qualification_id'];
        foreach ($requiredFields as $field) {
            if (empty($data[$field])) {
                $labels = ['full_name_ar' => 'الاسم بالعربي', 'national_id' => 'الرقم القومي', 'phone_mobile' => 'رقم المحمول', 'qualification_id' => 'المؤهل'];
                return $this->redirect("/transfers/{$id}/fill-form")->withError('الحقل مطلوب: ' . ($labels[$field] ?? $field));
            }
        }

        if ($nid !== '' && strlen($nid) === 14) {
            $activeConflict = $db->selectOne(
                "SELECT id, full_name_ar FROM members WHERE national_id = ? AND status = 'active' AND is_archived = 0",
                [$nid]
            );
            if ($activeConflict) {
                return $this->redirect("/transfers/{$id}/fill-form")->withError(
                    'يوجد عضو فعّال بنفس الرقم القومي: ' . $activeConflict['full_name_ar'] . ' (#' . $activeConflict['id'] . ') — لا يمكن إتمام الفصل'
                );
            }
        }

        // Store form data in notes JSON
        $existingNotes = !empty($transfer['notes']) ? json_decode($transfer['notes'], true) : [];
        if (!is_array($existingNotes)) $existingNotes = [];
        $existingNotes['form_data'] = $data;

        $db->update('transfer_requests', [
            'notes'      => json_encode($existingNotes, JSON_UNESCAPED_UNICODE),
            'status'     => 'form_filled',
            'updated_at' => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        // Auto-complete after form fill
        $result = TransferProcessor::execute((int) $id);
        if (!$result['success']) {
            return $this->redirect("/transfers/{$id}")->withError($result['error']);
        }

        return $this->redirect("/transfers/{$id}")->withSuccess(
            'تم ملء الاستمارة وإتمام الفصل — رقم العضوية الجديد: ' . $result['new_number']
        );
    }

    public function complete(Request $request, string $id): Response
    {
        $result = TransferProcessor::execute((int) $id);

        if (!$result['success']) {
            return $this->redirect("/transfers/{$id}")->withError($result['error']);
        }

        return $this->redirect("/transfers/{$id}")->withSuccess(
            'تم إتمام التحويل — رقم العضوية الجديد: ' . $result['new_number']
        );
    }

    public function preview(Request $request, string $memberId): Response
    {
        $feeCalc = SeparationFeeCalculator::calculate((int) $memberId);
        $db = App::getInstance()->db();
        $member = $db->selectOne("SELECT * FROM members WHERE id = ?", [(int) $memberId]);

        return $this->view('Transfers.Views.preview', [
            'member'  => $member,
            'feeCalc' => $feeCalc,
        ]);
    }

    public function calculateFee(Request $request): Response
    {
        $memberId      = (int) $request->post('member_id', 0);
        $childId       = $request->post('child_id') ? (int) $request->post('child_id') : null;
        $qualCode      = $request->post('qualification_code') ?: null;
        $transferType  = $request->post('transfer_type', '');

        if ($transferType === 'child_separation' && $childId) {
            $db = App::getInstance()->db();
            $child = $db->selectOne("SELECT date_of_birth, gender FROM children WHERE id = ?", [$childId]);
            $childGender = $request->post('child_gender', $child['gender'] ?? 'male');
            $depSpouses     = (int) $request->post('dep_spouses_count', 0);
            $depChildren    = (int) $request->post('dep_children_count', 0);
            $depTemps       = (int) $request->post('dep_temps_count', 0);

            if ($childGender === 'female') {
                // Female path: effective date = marriage_date
                $marriageDate = trim($request->post('marriage_date', '')) ?: null;
                if ($marriageDate) {
                    $result = SeparationFeeCalculator::calculateForChildSeparation(
                        $memberId, $childId, false, null,
                        $marriageDate, $qualCode,
                        $depSpouses, $depChildren, $depTemps
                    );
                    $result['effective_transfer_date'] = $marriageDate;
                    return $this->json($result);
                }
            } elseif ($child && !empty($child['date_of_birth'])) {
                // Male path: work + graduation + date_turned_25
                $isEmployedPost = $request->post('is_employed', '');
                $isEmployed     = $isEmployedPost !== '' ? (bool)(int)$isEmployedPost : false;
                $workDate       = trim($request->post('work_date', '')) ?: null;
                $graduationDate = trim($request->post('graduation_date', '')) ?: null;
                $date25Override = trim($request->post('date_turned_25', '')) ?: null;

                $dates = SeparationFeeCalculator::computeChildSeparationDates(
                    $child['date_of_birth'],
                    $isEmployed,
                    $isEmployed ? $workDate : null,
                    $date25Override,
                    $isEmployed ? $graduationDate : null
                );
                $result = SeparationFeeCalculator::calculateForChildSeparation(
                    $memberId, $childId, $isEmployed,
                    $isEmployed ? $workDate : null,
                    $dates['effective_transfer_date'],
                    $qualCode,
                    $depSpouses, $depChildren, $depTemps
                );
                $result['date_turned_25']          = $dates['date_turned_25'];
                $result['effective_transfer_date'] = $dates['effective_transfer_date'];
                return $this->json($result);
            }
        }

        $result = SeparationFeeCalculator::calculate($memberId, $childId, $qualCode);
        return $this->json($result);
    }
}