<?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]);

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

    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';

            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('يجب إدخال تاريخ الزواج لفصل الإناث');
                }
                $memberRecord = $db->selectOne("SELECT created_at, activated_at FROM members WHERE id = ?", [(int) $memberId]);
                $membershipStart = $memberRecord['activated_at'] ?? $memberRecord['created_at'] ?? null;
                if ($membershipStart && $marriageDate < substr($membershipStart, 0, 10)) {
                    return $this->redirect("/transfers/create/{$memberId}")->withError(
                        'تاريخ الزواج (' . $marriageDate . ') لا يمكن أن يسبق تاريخ إنشاء العضوية (' . substr($membershipStart, 0, 10) . '). يرجى مراجعة البيانات.'
                    );
                }
                $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'];
            }
        }

        // 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 = null;

        if ($transferType === 'child_separation' && $child && $effectiveTransferDate) {
            $feeCalc = SeparationFeeCalculator::calculateForChildSeparation(
                (int) $memberId,
                (int) $childId,
                (bool) $isEmployed,
                $workDate,
                $effectiveTransferDate,
                $qualCode,
                $depSpouses,
                $depChildren,
                $depTemps
            );
        } 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'];
                }
            }
        }

        $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'],
            '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,
        ]);

        // Send payment to cashier queue
        $amount = $totalWithSurcharge;
        if (bccomp((string) $amount, '0', 2) > 0) {
            // Build payment request notes with child name + fee breakdown for cashier display
            $paymentNotes = null;
            if ($transferType === 'child_separation' && $child) {
                $childName = $child['full_name_ar'] ?? '';
                $feeBreakdown = [];
                if (bccomp($feeCalc['separation_fee'] ?? '0', '0', 2) > 0) {
                    $feeBreakdown[] = 'رسوم الفصل: ' . money($feeCalc['separation_fee']);
                }
                if (bccomp($feeCalc['form_fee'] ?? '0', '0', 2) > 0) {
                    $feeBreakdown[] = 'رسوم الاستمارة: ' . money($feeCalc['form_fee']);
                }
                if (bccomp($feeCalc['annual_subscription_fee'] ?? '0', '0', 2) > 0) {
                    $feeBreakdown[] = 'الاشتراك السنوي: ' . money($feeCalc['annual_subscription_fee']);
                }
                if (bccomp($companionSurcharge, '0', 2) > 0) {
                    $feeBreakdown[] = 'فرق مرافقين: ' . money($companionSurcharge);
                }
                $feeBreakdown[] = '💵 الإجمالي: ' . money($amount);
                $paymentNotes = json_encode([
                    'child_name' => $childName,
                    'fee_breakdown' => $feeBreakdown,
                ], JSON_UNESCAPED_UNICODE);
            }

            $result = PaymentRequestService::createRequest([
                'member_id'           => (int) $memberId,
                'amount'              => $amount,
                'payment_type'        => 'separation_fee',
                'related_entity_type' => 'transfer_requests',
                'related_entity_id'   => (int) $transferReq->id,
                'description_ar'      => $transferType === 'child_separation' && $child
                    ? 'رسوم فصل — ' . ($child['full_name_ar'] ?? '') . ' — طلب #' . $transferReq->id
                    : 'رسوم تحويل/فصل — طلب #' . $transferReq->id,
                'notes'               => $paymentNotes,
            ]);

            if ($result['success']) {
                return $this->redirect("/transfers/{$transferReq->id}")->withSuccess(
                    'تم تقديم طلب التحويل/الفصل وإرسال طلب الدفع للخزينة — الإجمالي: ' . money($amount) . ' — رقم الطلب: ' . $result['request_number']
                );
            }

            return $this->redirect("/transfers/{$transferReq->id}")->withError(
                'تم تقديم الطلب لكن فشل إنشاء طلب الدفع: ' . ($result['error'] ?? 'خطأ غير معروف')
            );
        }

        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]);

        return $this->redirect("/transfers/{$id}")->withSuccess('تمت الموافقة على طلب التحويل');
    }

    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 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);
    }
}