<?php
declare(strict_types=1);

namespace App\Modules\Divorce\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Core\EventBus;
use App\Modules\Divorce\Models\DivorceCase;
use App\Modules\Divorce\Services\DivorceFeeCalculator;
use App\Modules\Archive\Services\ArchiveService;
use App\Modules\Members\Services\MemberNumberGenerator;
use App\Modules\Payments\Services\PaymentService;
use App\Modules\Cashier\Services\PaymentRequestService;

class DivorceController extends Controller
{
    public function index(Request $request): Response
    {
        $filters = ['search' => trim((string) $request->get('q', '')), 'status' => $request->get('status', '')];
        $page = max(1, (int) $request->get('page', 1));
        $result = DivorceCase::search($filters, 25, $page);
        return $this->view('Divorce.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('العضو غير موجود');
        $spouses = $db->select("SELECT * FROM spouses WHERE member_id = ? AND is_archived = 0 AND status = 'active'", [(int) $memberId]);
        if (empty($spouses)) return $this->redirect("/members/{$memberId}")->withError('لا يوجد زوج/زوجة مسجلة');
        $qualifications = $db->select("SELECT id, name_ar FROM qualifications WHERE is_active = 1 ORDER BY sort_order");
        $valueInfo = DivorceFeeCalculator::getCurrentMembershipValue($member);
        return $this->view('Divorce.Views.create', [
            'member' => $member,
            'spouses' => $spouses,
            'qualifications' => $qualifications,
            'currentMembershipValue' => $valueInfo['value'],
            'membershipValueSource' => $valueInfo['source'],
        ]);
    }

    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('العضو غير موجود');

        $spouseId = (int) $request->post('spouse_id', 0);
        $divorceDate = trim($request->post('divorce_date', ''));
        $qualificationId = (int) $request->post('spouse_qualification_id', 0);
        $notes = trim($request->post('notes', ''));

        if (!$spouseId || !$divorceDate || !$qualificationId) {
            return $this->redirect("/divorce/create/{$memberId}")->withError('جميع البيانات مطلوبة (الزوج/ة، التاريخ، المؤهل، قسيمة الطلاق)');
        }

        // Handle divorce certificate upload
        $certPath = null;
        if (!empty($_FILES['divorce_certificate']['tmp_name'])) {
            $file = $_FILES['divorce_certificate'];
            $maxSize = 5 * 1024 * 1024;
            if ($file['size'] > $maxSize) {
                return $this->redirect("/divorce/create/{$memberId}")->withError('حجم الملف أكبر من 5 ميجا');
            }
            $allowed = ['application/pdf', 'image/jpeg', 'image/png', 'image/jpg'];
            if (!in_array($file['type'], $allowed, true)) {
                return $this->redirect("/divorce/create/{$memberId}")->withError('نوع الملف غير مسموح — PDF أو صور فقط');
            }
            $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
            $storedName = 'divorce_cert_' . time() . '_' . $spouseId . '.' . $ext;
            $uploadDir = App::getInstance()->basePath() . '/storage/uploads/divorce/';
            if (!is_dir($uploadDir)) mkdir($uploadDir, 0755, true);
            if (move_uploaded_file($file['tmp_name'], $uploadDir . $storedName)) {
                $certPath = 'storage/uploads/divorce/' . $storedName;
            }
        }

        if (!$certPath) {
            return $this->redirect("/divorce/create/{$memberId}")->withError('قسيمة الطلاق مطلوبة');
        }

        $feeCalc = DivorceFeeCalculator::calculate((int) $memberId, $spouseId, $divorceDate);
        if (!($feeCalc['success'] ?? false)) {
            return $this->redirect("/divorce/create/{$memberId}")->withError($feeCalc['error'] ?? 'خطأ');
        }

        $spouse = $db->selectOne("SELECT * FROM spouses WHERE id = ?", [$spouseId]);

        $case = DivorceCase::create([
            'member_id'                   => (int) $memberId,
            'spouse_id'                   => $spouseId,
            'divorce_date'                => $divorceDate,
            'divorce_certificate_path'    => $certPath,
            'spouse_qualification_id'     => $qualificationId,
            'divorce_case_type'           => $feeCalc['case_type'],
            'request_date'                => date('Y-m-d'),
            'membership_acquisition_date' => substr($spouse['join_date'] ?? $spouse['created_at'] ?? '', 0, 10),
            'years_of_membership'         => $feeCalc['years_of_membership'],
            'has_children_on_membership'  => $feeCalc['has_children'] ? 1 : 0,
            'status'                      => 'board_review',
            'notes'                       => $notes ?: null,
        ]);

        EventBus::dispatch('divorce.submitted', ['case_id' => (int) $case->id, 'member_id' => (int) $memberId]);

        return $this->redirect("/divorce/{$case->id}")->withSuccess('تم تقديم طلب الطلاق وإرساله لمجلس الأمناء للمراجعة');
    }

    public function boardApprove(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $case = $db->selectOne("SELECT * FROM divorce_cases WHERE id = ?", [(int) $id]);
        if (!$case || $case['status'] !== 'board_review') {
            return $this->redirect('/divorce')->withError('الحالة غير صالحة للمراجعة');
        }

        $feePercentage = trim($request->post('fee_percentage', ''));
        $boardDecisionNumber = trim($request->post('board_decision_number', ''));
        $boardDecisionDate = trim($request->post('board_decision_date', ''));
        $boardNotes = trim($request->post('board_notes', ''));

        if ($feePercentage === '' || !is_numeric($feePercentage)) {
            return $this->redirect("/divorce/{$id}")->withError('يجب تحديد نسبة الرسوم');
        }

        $feePercentage = (string) $feePercentage;
        $member = $db->selectOne("SELECT * FROM members WHERE id = ?", [(int) $case['member_id']]);

        // Use current membership value from pricing_configs (not stored member value)
        $valueInfo = DivorceFeeCalculator::getCurrentMembershipValue($member);
        $membershipValue = $valueInfo['value'];

        // Calculate fees: percentage * membership_value + form fee (570) + annual subscription
        $percentageFee = bcdiv(bcmul($membershipValue, $feePercentage, 4), '100', 2);
        $formFee = DivorceFeeCalculator::getFormFee();
        $annualSub = DivorceFeeCalculator::getAnnualSubscription();

        // Children to transfer (no fees — fees only apply when adding NEW children after separation)
        $childrenSelected = $request->post('children', []);
        $childrenAssignment = [];

        if (!empty($childrenSelected) && is_array($childrenSelected)) {
            $children = $db->select(
                "SELECT id, full_name_ar, date_of_birth FROM children WHERE member_id = ? AND is_archived = 0 AND status = 'active'",
                [(int) $case['member_id']]
            );
            foreach ($children as $child) {
                if (in_array((string) $child['id'], $childrenSelected, true)) {
                    $childrenAssignment[] = [
                        'id' => (int) $child['id'],
                        'name' => $child['full_name_ar'],
                    ];
                }
            }
        }

        $totalFee = bcadd(bcadd($percentageFee, $formFee, 2), $annualSub, 2);

        $db->update('divorce_cases', [
            'fee_percentage'          => $feePercentage,
            'fee_amount'              => $percentageFee,
            'form_fee'                => $formFee,
            'annual_subscription_fee' => $annualSub,
            'total_fee'               => $totalFee,
            'board_decision_number'   => $boardDecisionNumber ?: null,
            'board_decision_date'     => $boardDecisionDate ?: null,
            'board_notes'             => $boardNotes ?: null,
            'children_assignment_json' => !empty($childrenAssignment) ? json_encode($childrenAssignment, JSON_UNESCAPED_UNICODE) : null,
            'status'                  => 'board_approved',
            'updated_at'              => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        // Auto-send payment request to cashier
        $breakdown = [
            'قيمة العضوية الحالية: ' . money($membershipValue) . ($valueInfo['source'] === 'pricing_configs' ? ' (من جدول الأسعار)' : ''),
            'النسبة المقررة: ' . $feePercentage . '%',
            'رسوم الطلاق: ' . money($percentageFee),
            'رسوم استمارة (570): ' . money($formFee),
            'اشتراك سنوي: ' . money($annualSub),
        ];
        if (!empty($childrenAssignment)) {
            $breakdown[] = 'نقل أبناء (بدون رسوم): ' . count($childrenAssignment) . ' أبناء';
        }
        $breakdown[] = '═══════════════════════════';
        $breakdown[] = 'الإجمالي: ' . money($totalFee);

        PaymentRequestService::createRequest([
            'member_id'           => (int) $case['member_id'],
            'amount'              => $totalFee,
            'payment_type'        => 'divorce_fee',
            'related_entity_type' => 'divorce_cases',
            'related_entity_id'   => (int) $id,
            'description_ar'      => 'رسوم طلاق — حالة #' . $id . ' (قرار مجلس الأمناء)',
            'notes'               => json_encode(['fee_breakdown' => $breakdown], JSON_UNESCAPED_UNICODE),
        ]);

        EventBus::dispatch('divorce.board_approved', ['case_id' => (int) $id, 'fee_percentage' => $feePercentage]);

        return $this->redirect("/divorce/{$id}")->withSuccess(
            'تم اعتماد مجلس الأمناء — النسبة: ' . $feePercentage . '% — الإجمالي: ' . money($totalFee) . ' — تم إرسال طلب الدفع للخزينة'
        );
    }

    public function boardReject(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $case = $db->selectOne("SELECT * FROM divorce_cases WHERE id = ?", [(int) $id]);
        if (!$case || $case['status'] !== 'board_review') {
            return $this->redirect('/divorce')->withError('الحالة غير صالحة');
        }

        $boardNotes = trim($request->post('board_notes', ''));

        $db->update('divorce_cases', [
            'status'      => 'rejected',
            'board_notes' => $boardNotes ?: 'مرفوض من مجلس الأمناء',
            'updated_at'  => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        EventBus::dispatch('divorce.rejected', ['case_id' => (int) $id]);

        return $this->redirect("/divorce/{$id}")->withSuccess('تم رفض طلب الطلاق');
    }

    public function show(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $case = $db->selectOne(
            "SELECT dc.*, m.full_name_ar as member_name, m.membership_number, m.membership_value,
                    m.branch_id, m.qualification_id,
                    s.full_name_ar as spouse_name, s.spouse_order, s.join_date as spouse_join_date,
                    q.name_ar as qualification_name
             FROM divorce_cases dc
             JOIN members m ON m.id = dc.member_id
             JOIN spouses s ON s.id = dc.spouse_id
             LEFT JOIN qualifications q ON q.id = dc.spouse_qualification_id
             WHERE dc.id = ?",
            [(int) $id]
        );
        if (!$case) return $this->redirect('/divorce')->withError('الحالة غير موجودة');

        // Get current membership value from pricing_configs
        $valueInfo = DivorceFeeCalculator::getCurrentMembershipValue($case);
        $currentMembershipValue = $valueInfo['value'];
        $membershipValueSource = $valueInfo['source'];

        $children = [];
        $suggestedPercentage = null;

        if ($case['status'] === 'board_review') {
            $feeCalc = DivorceFeeCalculator::calculate((int) $case['member_id'], (int) $case['spouse_id'], $case['divorce_date']);
            if ($feeCalc['success'] ?? false) {
                $suggestedPercentage = $feeCalc['suggested_percentage'] ?? null;
            }
            // Load children for transfer selection (no fees — fees only on new additions after separation)
            $db = App::getInstance()->db();
            $children = $db->select(
                "SELECT id, full_name_ar, date_of_birth FROM children WHERE member_id = ? AND is_archived = 0 AND status = 'active'",
                [(int) $case['member_id']]
            );
        }

        return $this->view('Divorce.Views.show', [
            'case' => $case,
            'children' => $children,
            'suggestedPercentage' => $suggestedPercentage,
            'currentMembershipValue' => $currentMembershipValue,
            'membershipValueSource' => $membershipValueSource,
        ]);
    }

    public function pay(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $case = $db->selectOne("SELECT * FROM divorce_cases WHERE id = ?", [(int) $id]);
        if (!$case) return $this->redirect('/divorce')->withError('الحالة غير موجودة');
        if (in_array($case['status'], ['completed', 'fee_paid'], true)) {
            return $this->redirect("/divorce/{$id}")->withError('تم دفع الرسوم مسبقاً');
        }
        if ($case['status'] !== 'board_approved') {
            return $this->redirect("/divorce/{$id}")->withError('يجب اعتماد مجلس الأمناء أولاً');
        }

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

        $result = PaymentService::processPayment([
            'member_id'           => (int) $case['member_id'],
            'amount'              => $amount,
            'payment_type'        => 'divorce_fee',
            'payment_method'      => $request->post('payment_method', 'cash'),
            'related_entity_type' => 'divorce_cases',
            'related_entity_id'   => (int) $id,
            'description'         => 'رسوم طلاق — حالة #' . $id,
        ]);

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

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

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

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

    public function complete(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $case = $db->selectOne("SELECT * FROM divorce_cases WHERE id = ?", [(int) $id]);
        if (!$case || !in_array($case['status'], ['board_approved', 'fee_paid'], true)) {
            return $this->redirect('/divorce')->withError('الحالة غير صالحة — يجب اعتماد مجلس الأمناء والسداد أولاً');
        }

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

        $debtCheck = \App\Shared\Services\DebtCheckService::check((int) $case['member_id']);
        if (!$debtCheck['clear']) {
            return $this->redirect("/divorce/{$id}")->withError('لا يمكن إتمام الطلاق — مديونيات بإجمالي ' . $debtCheck['total'] . ' ج.م. يرجى سدادها أولاً.');
        }

        $db->beginTransaction();
        try {
            $snapshotId = ArchiveService::takeSnapshot('members', (int) $case['member_id'], 'divorce', 'طلاق — حالة #' . $id);

            $spouse = $db->selectOne("SELECT * FROM spouses WHERE id = ?", [(int) $case['spouse_id']]);
            $member = $db->selectOne("SELECT * FROM members WHERE id = ?", [(int) $case['member_id']]);

            // Create new independent member from spouse data
            $newMemberId = $db->insert('members', [
                'full_name_ar'                => $spouse['full_name_ar'],
                'full_name_en'                => $spouse['full_name_en'] ?? null,
                'national_id'                 => $spouse['national_id'],
                'date_of_birth'               => $spouse['date_of_birth'],
                'age_years'                   => $spouse['age_years'],
                'age_months'                  => $spouse['age_months'],
                'gender'                      => $spouse['gender'],
                'nationality'                 => $spouse['nationality'] ?? 'مصري',
                'branch_id'                   => (int) $member['branch_id'],
                'membership_type'             => $member['membership_type'] ?? 'working',
                'member_category'             => 'working_member',
                'status'                      => 'active',
                'qualification_id'            => $case['spouse_qualification_id'] ?? $spouse['qualification_id'] ?? $member['qualification_id'],
                'phone_mobile'                => $spouse['mobile'] ?? $member['phone_mobile'],
                'membership_value'            => $member['membership_value'],
                'transferred_from_divorce_id' => (int) $id,
                'original_membership_number'  => $member['membership_number'],
                'created_at'                  => date('Y-m-d H:i:s'),
                'updated_at'                  => date('Y-m-d H:i:s'),
                'created_by'                  => $employee ? (int) $employee->id : null,
            ]);

            $newNumber = MemberNumberGenerator::assign($newMemberId);

            // Archive spouse on original member
            $db->update('spouses', [
                'status' => 'divorced',
                'is_archived' => 1,
                'archived_at' => date('Y-m-d H:i:s'),
            ], '`id` = ?', [(int) $case['spouse_id']]);

            // Transfer children if assigned
            $childrenTransferred = 0;
            if (!empty($case['children_assignment_json'])) {
                $assignedChildren = json_decode($case['children_assignment_json'], true);
                if (is_array($assignedChildren)) {
                    $childIds = array_column($assignedChildren, 'id');
                    foreach ($childIds as $childId) {
                        $db->query(
                            "UPDATE children SET member_id = ?, updated_at = NOW() WHERE id = ? AND member_id = ?",
                            [$newMemberId, (int) $childId, (int) $case['member_id']]
                        );
                        $childrenTransferred++;
                    }
                }
            }

            // Update case with new membership references
            $db->update('divorce_cases', [
                'spouse_new_member_id'         => $newMemberId,
                'spouse_new_membership_number'  => $newNumber,
                'original_member_id'           => (int) $case['member_id'],
                'original_membership_number'   => $member['membership_number'],
                'archive_snapshot_id'          => $snapshotId,
                'status'                       => 'completed',
                'updated_at'                   => date('Y-m-d H:i:s'),
            ], '`id` = ?', [(int) $id]);

            ArchiveService::recordNumberTransfer($newNumber, 'divorce', 'members', $newMemberId);

            $db->commit();

            EventBus::dispatch('divorce.completed', [
                'case_id' => (int) $id,
                'new_member_id' => $newMemberId,
                'new_number' => $newNumber,
                'children_transferred' => $childrenTransferred,
            ]);

            $msg = 'تم إتمام حالة الطلاق — رقم العضوية الجديد: ' . $newNumber;
            if ($childrenTransferred > 0) {
                $msg .= ' — تم نقل ' . $childrenTransferred . ' أبناء';
            }

            return $this->redirect("/divorce/{$id}")->withSuccess($msg);
        } catch (\Throwable $e) {
            $db->rollBack();
            return $this->redirect("/divorce/{$id}")->withError('فشل: ' . $e->getMessage());
        }
    }
}
