<?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('لا يوجد زوج/زوجة مسجلة');
        return $this->view('Divorce.Views.create', ['member' => $member, '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('العضو غير موجود');

        $spouseId = (int) $request->post('spouse_id', 0);
        $divorceDate = trim($request->post('divorce_date', ''));
        $notes = trim($request->post('notes', ''));
        $paymentMethod = trim($request->post('payment_method', 'cash'));

        if (!$spouseId || !$divorceDate) {
            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'] ?? 'خطأ');
        }

        $case = DivorceCase::create([
            'member_id'                   => (int) $memberId,
            'spouse_id'                   => $spouseId,
            'divorce_date'                => $divorceDate,
            'divorce_case_type'           => $feeCalc['case_type'],
            'request_date'                => date('Y-m-d'),
            'membership_acquisition_date' => substr($member['created_at'] ?? '', 0, 10),
            'years_of_membership'         => $feeCalc['years_of_membership'],
            'has_children_on_membership'  => $feeCalc['has_children'] ? 1 : 0,
            'fee_percentage'              => $feeCalc['fee_percentage'],
            'fee_amount'                  => $feeCalc['total_fee'],
            'status'                      => 'submitted',
            'notes'                       => $notes ?: null,
        ]);

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

        // Send payment to cashier queue
        $amount = $feeCalc['total_fee'] ?? '0.00';
        if (bccomp((string) $amount, '0', 2) > 0) {
            $caseTypeLabel = DivorceCase::getCaseTypeLabel($feeCalc['case_type']);
            $breakdown = [
                '📋 نوع الحالة: ' . $caseTypeLabel,
                '💰 قيمة العضوية: ' . money($feeCalc['membership_value']),
                '📊 النسبة: ' . $feeCalc['fee_percentage'] . '%',
                '💵 رسوم الطلاق: ' . money($feeCalc['fee_amount']),
                '📝 رسوم استمارة نقل: ' . money($feeCalc['form_fee']),
                '═══════════════════════════',
                '💵 الإجمالي: ' . money($amount),
            ];

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

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

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

        return $this->redirect("/divorce/{$case->id}")->withSuccess('تم تسجيل حالة الطلاق — النوع: ' . DivorceCase::getCaseTypeLabel($feeCalc['case_type']) . ' — الرسوم: ' . money($feeCalc['total_fee']));
    }

    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,
                    s.full_name_ar as spouse_name
             FROM divorce_cases dc JOIN members m ON m.id = dc.member_id JOIN spouses s ON s.id = dc.spouse_id WHERE dc.id = ?",
            [(int) $id]
        );
        if (!$case) return $this->redirect('/divorce')->withError('الحالة غير موجودة');

        // Compute fee breakdown from stored data
        $membershipValue = $case['membership_value'] ?? '0.00';
        $feePercentage = $case['fee_percentage'] ?? '0';
        $percentageFee = bcdiv(bcmul($membershipValue, (string) $feePercentage, 4), '100', 2);
        $totalFee = $case['fee_amount'] ?? '0.00';
        $formFee = bcsub($totalFee, $percentageFee, 2);

        return $this->view('Divorce.Views.show', [
            'case'          => $case,
            'percentageFee' => $percentageFee,
            'formFee'       => $formFee,
        ]);
    }

    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 ($case['status'] === 'completed' || $case['status'] === 'fee_paid') {
            return $this->redirect("/divorce/{$id}")->withError('تم دفع الرسوم مسبقاً');
        }

        $amount = $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 || $case['status'] === 'completed') return $this->redirect('/divorce')->withError('الحالة غير صالحة');

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

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

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

            $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'  => 'working',
                'member_category'  => 'working_member',
                'status'           => 'active',
                'qualification_id' => $spouse['qualification_id'] ?? $member['qualification_id'],
                'phone_mobile'     => $spouse['mobile'] ?? $member['phone_mobile'],
                'membership_value' => $member['membership_value'],
                '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
            $db->update('spouses', ['status' => 'divorced', 'is_archived' => 1, 'archived_at' => date('Y-m-d H:i:s')], '`id` = ?', [(int) $case['spouse_id']]);

            // Update case
            $db->update('divorce_cases', [
                'spouse_new_member_id'        => $newMemberId,
                'spouse_new_membership_number' => $newNumber,
                '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]);

            return $this->redirect("/divorce/{$id}")->withSuccess('تم إتمام حالة الطلاق — رقم العضوية الجديد: ' . $newNumber);
        } catch (\Throwable $e) {
            $db->rollBack();
            return $this->redirect("/divorce/{$id}")->withError('فشل: ' . $e->getMessage());
        }
    }
}