<?php
declare(strict_types=1);

namespace App\Modules\Death\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Core\EventBus;
use App\Modules\Death\Models\DeathCase;
use App\Modules\Archive\Services\ArchiveService;
use App\Modules\Rules\Services\RuleEngine;
use App\Modules\Payments\Services\PaymentService;
use App\Modules\Cashier\Services\PaymentRequestService;
use App\Modules\ServiceCatalog\Models\ServicePrice;

class DeathController 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 = DeathCase::search($filters, 25, $page);
        return $this->view('Death.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]);

        // Pre-calculate fees to show on form
        $formFee = ServicePrice::getPrice('SVC_TRANSFER_FORM', '570.00');
        $annualSubBase = ServicePrice::getPrice('SVC_ANNUAL_MEMBER', '492.00');
        $devFeeData = RuleEngine::get('DEVELOPMENT_FEE');
        $devFee = $devFeeData['amount'] ?? '35.00';
        $annualSub = bcadd($annualSubBase, $devFee, 2);
        $totalFee = bcadd($formFee, $annualSub, 2);

        return $this->view('Death.Views.create', [
            'member'     => $member,
            'spouses'    => $spouses,
            'form_fee'   => $formFee,
            'annual_sub' => $annualSub,
            'total_fee'  => $totalFee,
        ]);
    }

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

        $deceasedType = trim($request->post('deceased_type', ''));
        $deathDate = trim($request->post('death_date', ''));
        $certNumber = trim($request->post('death_certificate_number', ''));
        $spouseId = $request->post('spouse_id') ? (int) $request->post('spouse_id') : null;
        $notes = trim($request->post('notes', ''));
        $paymentMethod = trim($request->post('payment_method', 'cash'));

        if (!$deceasedType || !$deathDate) {
            return $this->redirect("/death/create/{$memberId}")->withError('بيانات الوفاة غير مكتملة');
        }

        // Calculate fee (form fee + annual renewal)
        $formFee = ServicePrice::getPrice('SVC_TRANSFER_FORM', '570.00');
        $annualSubBase = ServicePrice::getPrice('SVC_ANNUAL_MEMBER', '492.00');
        $devFeeData = RuleEngine::get('DEVELOPMENT_FEE');
        $devFee = $devFeeData['amount'] ?? '35.00';
        $annualSub = bcadd($annualSubBase, $devFee, 2);
        $totalFee = bcadd($formFee, $annualSub, 2);

        $case = DeathCase::create([
            'member_id'                 => (int) $memberId,
            'deceased_type'             => $deceasedType,
            'death_date'                => $deathDate,
            'death_certificate_number'  => $certNumber ?: null,
            'spouse_id'                 => $spouseId,
            'same_membership_number'    => ($deceasedType === 'primary_member') ? 1 : 0,
            'fee_amount'                => $totalFee,
            'status'                    => 'recorded',
            'notes'                     => $notes ?: null,
        ]);

        EventBus::dispatch('death.recorded', ['case_id' => (int) $case->id, 'member_id' => (int) $memberId, 'type' => $deceasedType]);

        // Send payment to cashier queue
        if (bccomp($totalFee, '0', 2) > 0) {
            $deceasedLabel = match ($deceasedType) {
                'primary_member' => 'العضو الأصلي',
                'spouse' => 'الزوج/ة',
                default => $deceasedType,
            };
            $breakdown = [
                '📋 نوع الوفاة: ' . $deceasedLabel,
                '📝 رسوم استمارة نقل: ' . money($formFee),
                '📅 اشتراك سنوي: ' . money($annualSubBase) . ' + تنمية ' . money($devFee) . ' = ' . money($annualSub),
                '═══════════════════════════',
                '💵 الإجمالي: ' . money($totalFee),
            ];

            $result = PaymentRequestService::createRequest([
                'member_id'           => (int) $memberId,
                'amount'              => $totalFee,
                'payment_type'        => 'death_fee',
                'related_entity_type' => 'death_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("/death/{$case->id}")->withSuccess(
                    'تم تسجيل حالة الوفاة وإرسال طلب الدفع للخزينة — ' . money($totalFee) . ' — رقم الطلب: ' . $result['request_number']
                );
            }

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

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

        // Compute fee breakdown components
        $formFee = ServicePrice::getPrice('SVC_TRANSFER_FORM', '570.00');
        $annualSubBase = ServicePrice::getPrice('SVC_ANNUAL_MEMBER', '492.00');
        $devFeeData = RuleEngine::get('DEVELOPMENT_FEE');
        $devFee = $devFeeData['amount'] ?? '35.00';
        $annualSub = bcadd($annualSubBase, $devFee, 2);

        return $this->view('Death.Views.show', [
            'case'           => $case,
            'formFee'        => $formFee,
            'annualSubBase'  => $annualSubBase,
            'devFee'         => $devFee,
            'annualSub'      => $annualSub,
        ]);
    }

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

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

        $result = PaymentService::processPayment([
            'member_id'           => (int) $case['member_id'],
            'amount'              => $amount,
            'payment_type'        => 'death_fee',
            'payment_method'      => $request->post('payment_method', 'cash'),
            'related_entity_type' => 'death_cases',
            'related_entity_id'   => (int) $id,
            'description'         => 'رسوم وفاة (استمارة + اشتراك) — حالة #' . $id,
        ]);

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

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

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

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

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

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

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

            if ($case['deceased_type'] === 'spouse' && $case['spouse_id']) {
                // Spouse death: archive spouse
                $db->update('spouses', [
                    'status' => 'deceased', 'is_archived' => 1,
                    'archived_at' => date('Y-m-d H:i:s'),
                ], '`id` = ?', [(int) $case['spouse_id']]);
            } elseif ($case['deceased_type'] === 'primary_member') {
                // Primary member death: transfer to spouse with SAME number
                $member = $db->selectOne("SELECT * FROM members WHERE id = ?", [(int) $case['member_id']]);
                $spouse = $case['spouse_id'] ? $db->selectOne("SELECT * FROM spouses WHERE id = ?", [(int) $case['spouse_id']]) : null;

                if ($spouse) {
                    // Create new member from spouse data with SAME membership number
                    $newMemberId = $db->insert('members', [
                        'membership_number' => $member['membership_number'], // SAME number
                        'full_name_ar'      => $spouse['full_name_ar'],
                        'national_id'       => $spouse['national_id'],
                        'date_of_birth'     => $spouse['date_of_birth'],
                        'age_years'         => $spouse['age_years'],
                        'gender'            => $spouse['gender'],
                        'nationality'       => $spouse['nationality'] ?? 'مصري',
                        'branch_id'         => (int) $member['branch_id'],
                        'membership_type'   => 'working',
                        'status'            => 'active',
                        '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,
                    ]);

                    // Archive old member
                    $db->update('members', [
                        'is_archived' => 1, 'archived_at' => date('Y-m-d H:i:s'),
                        'status' => 'deceased', 'membership_number' => null,
                    ], '`id` = ?', [(int) $case['member_id']]);

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

                    // Transfer children to new member
                    $db->update('children', ['member_id' => $newMemberId, 'updated_at' => date('Y-m-d H:i:s')],
                        '`member_id` = ? AND `is_archived` = 0', [(int) $case['member_id']]);

                    // Record number chain
                    ArchiveService::recordNumberTransfer($member['membership_number'], 'death_transfer', 'members', $newMemberId);

                    $db->update('death_cases', [
                        'transferred_to_member_id' => $newMemberId,
                        'archive_snapshot_id'      => $snapshotId,
                        'status'                   => 'completed',
                        'updated_at'               => date('Y-m-d H:i:s'),
                    ], '`id` = ?', [(int) $id]);

                    $db->commit();
                    EventBus::dispatch('death.completed', ['case_id' => (int) $id, 'new_member_id' => $newMemberId]);
                    return $this->redirect("/death/{$id}")->withSuccess('تم نقل العضوية للزوج/ة بنفس رقم العضوية');
                }
            }

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

            $db->commit();
            return $this->redirect("/death/{$id}")->withSuccess('تم إتمام حالة الوفاة');
        } catch (\Throwable $e) {
            $db->rollBack();
            return $this->redirect("/death/{$id}")->withError('فشل: ' . $e->getMessage());
        }
    }
}