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

        $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('قسيمة الطلاق مطلوبة');
        }

        // Validate basic eligibility
        $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_certificate_path'    => $certPath,
            'spouse_qualification_id'     => $qualificationId,
            '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,
            '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']]);
        $membershipValue = $member['membership_value'] ?? '0.00';

        // Calculate fees: percentage * membership_value + form fee (570) + annual subscription
        $percentageFee = bcdiv(bcmul($membershipValue, $feePercentage, 4), '100', 2);
        $formFee = DivorceFeeCalculator::getFormFee();
        $annualSub = DivorceFeeCalculator::getAnnualSubscription();
        $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,
            'status'                => 'board_approved',
            'updated_at'            => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        // Auto-send payment request to cashier
        $breakdown = [
            'قيمة العضوية: ' . money($membershipValue),
            'النسبة المقررة: ' . $feePercentage . '%',
            'رسوم الطلاق: ' . money($percentageFee),
            'رسوم استمارة (570): ' . money($formFee),
            'اشتراك سنوي: ' . money($annualSub),
            '═══════════════════════════',
            'الإجمالي: ' . 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,
                    s.full_name_ar as spouse_name, 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('الحالة غير موجودة');

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

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

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

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

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

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