<?php
declare(strict_types=1);

namespace App\Modules\Foreign\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Core\EventBus;
use App\Modules\Foreign\Models\ForeignMemberDetail;
use App\Modules\Rules\Services\RuleEngine;
use App\Modules\Payments\Services\PaymentService;

class ForeignController extends Controller
{
    public function index(Request $request): Response
    {
        $rows = ForeignMemberDetail::getAllActive();
        return $this->view('Foreign.Views.index', ['rows' => $rows]);
    }

    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('العضو غير موجود');
        if (($member['membership_type'] ?? 'working') !== 'foreign') {
            return $this->redirect("/members/{$memberId}")->withError('هذا العضو ليس عضواً أجنبياً');
        }

        $countries = $db->select("SELECT id, name_ar, nationality_ar FROM countries WHERE is_active = 1 ORDER BY name_ar");

        $branchCode = 'sheraton';
        if ($member['branch_id']) {
            $branch = $db->selectOne("SELECT branch_code FROM branches WHERE id = ?", [(int) $member['branch_id']]);
            $branchCode = $branch['branch_code'] ?? 'sheraton';
        }

        $feeRuleCode = $branchCode === 'new_capital' ? 'FOREIGN_MEMBER_FEE_CAPITAL' : 'FOREIGN_MEMBER_FEE_SHERATON';
        $feeData = RuleEngine::get($feeRuleCode);
        $feeUsd = $feeData['amount_usd'] ?? '10000.00';

        return $this->view('Foreign.Views.create', [
            'member'    => $member,
            'countries' => $countries,
            'fee_usd'   => $feeUsd,
        ]);
    }

    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('العضو غير موجود');
        if (($member['membership_type'] ?? 'working') !== 'foreign') {
            return $this->redirect("/members/{$memberId}")->withError('هذا العضو ليس عضواً أجنبياً');
        }

        $data = $request->all();
        unset($data['_csrf_token']);

        $errors = [];
        if (empty(trim($data['passport_number'] ?? ''))) $errors[] = 'رقم جواز السفر مطلوب';
        if (empty($data['issuing_country_id'] ?? '')) $errors[] = 'بلد الإصدار مطلوب';
        if (empty($data['nationality_country_id'] ?? '')) $errors[] = 'الجنسية مطلوبة';
        if (empty($data['passport_issue_date'] ?? '')) $errors[] = 'تاريخ الإصدار مطلوب';
        if (empty($data['passport_expiry_date'] ?? '')) $errors[] = 'تاريخ الانتهاء مطلوب';

        if (!empty($data['passport_expiry_date'])) {
            $minMonthsData = RuleEngine::get('PASSPORT_MIN_VALIDITY_MONTHS');
            $minMonths = $minMonthsData['months'] ?? 6;
            $minDate = date('Y-m-d', strtotime("+{$minMonths} months"));
            if ($data['passport_expiry_date'] < $minDate) {
                $errors[] = "جواز السفر يجب أن يكون صالحاً لمدة {$minMonths} أشهر على الأقل";
            }
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
            $session->flash('_old_input', $data);
            return $this->redirect("/members/{$memberId}/foreign/create");
        }

        $branchCode = 'sheraton';
        if ($member['branch_id']) {
            $branch = $db->selectOne("SELECT branch_code FROM branches WHERE id = ?", [(int) $member['branch_id']]);
            $branchCode = $branch['branch_code'] ?? 'sheraton';
        }
        $feeRuleCode = $branchCode === 'new_capital' ? 'FOREIGN_MEMBER_FEE_CAPITAL' : 'FOREIGN_MEMBER_FEE_SHERATON';
        $feeData = RuleEngine::get($feeRuleCode);
        $feeUsd = $feeData['amount_usd'] ?? '10000.00';

        $exchangeRate = trim($data['exchange_rate'] ?? '');
        $feeEgp = null;
        if ($exchangeRate !== '' && is_numeric($exchangeRate)) {
            $feeEgp = bcmul($feeUsd, $exchangeRate, 2);
        }

        $foreign = ForeignMemberDetail::create([
            'member_id'              => (int) $memberId,
            'passport_number'        => trim($data['passport_number']),
            'issuing_country_id'     => (int) $data['issuing_country_id'],
            'nationality_country_id' => (int) $data['nationality_country_id'],
            'passport_issue_date'    => $data['passport_issue_date'],
            'passport_expiry_date'   => $data['passport_expiry_date'],
            'place_of_birth'         => trim($data['place_of_birth'] ?? ''),
            'fee_amount_usd'         => $feeUsd,
            'exchange_rate'          => $exchangeRate ?: null,
            'fee_amount_egp'         => $feeEgp,
            'status'                 => 'active',
            'notes'                  => $data['notes'] ?? null,
        ]);

        // membership_type already set at creation — no update needed

        // Process payment through central PaymentService (use EGP amount if available, otherwise USD)
        $chargeAmount = $feeEgp ?? $feeUsd;
        $chargeCurrency = $feeEgp ? 'EGP' : 'USD';
        if (bccomp((string) $chargeAmount, '0.00', 2) > 0) {
            $payResult = PaymentService::processPayment([
                'member_id'           => (int) $memberId,
                'amount'              => (string) $chargeAmount,
                'payment_type'        => 'membership_fee',
                'payment_method'      => $data['payment_method'] ?? 'cash',
                'currency'            => $chargeCurrency,
                'related_entity_type' => 'foreign_member_details',
                'related_entity_id'   => (int) $foreign->id,
                'description'         => 'رسوم عضوية أجنبية — ' . number_format((float) $feeUsd, 2) . ' USD',
            ]);

            if (!$payResult['success']) {
                return $this->redirect("/members/{$memberId}")
                    ->withError('تم تسجيل العضوية الأجنبية لكن فشل تسجيل الدفع: ' . ($payResult['error'] ?? ''));
            }
        }

        EventBus::dispatch('foreign.registered', ['member_id' => (int) $memberId, 'foreign_id' => (int) $foreign->id]);

        return $this->redirect("/members/{$memberId}")->withSuccess('تم تسجيل العضوية الأجنبية — الرسوم: ' . number_format((float) $feeUsd, 2) . ' USD');
    }
}