<?php
declare(strict_types=1);

namespace App\Modules\Seasonal\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Core\EventBus;
use App\Modules\Seasonal\Models\SeasonalMembership;
use App\Modules\Seasonal\Services\SeasonalPricingService;
use App\Modules\Cashier\Services\PaymentRequestService;

class SeasonalController extends Controller
{
    public function index(Request $request): Response
    {
        $db = App::getInstance()->db();
        $status = $request->get('status', '');

        $where = 's.is_archived = 0';
        $params = [];
        if ($status !== '') {
            $where .= ' AND s.status = ?';
            $params[] = $status;
        }

        $rows = $db->select(
            "SELECT s.*, m.full_name_ar as member_name, m.membership_number, b.name_ar as branch_name
             FROM seasonal_memberships s
             JOIN members m ON m.id = s.member_id
             JOIN branches b ON b.id = s.branch_id
             WHERE {$where}
             ORDER BY s.created_at DESC LIMIT 100",
            $params
        );

        return $this->view('Seasonal.Views.index', ['rows' => $rows, 'status' => $status]);
    }

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

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

        $spouses = $db->select("SELECT id, full_name_ar FROM spouses WHERE member_id = ? AND is_archived = 0 AND status = 'active'", [(int) $memberId]);
        $children = $db->select("SELECT id, full_name_ar, date_of_birth, gender, TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) as age FROM children WHERE member_id = ? AND is_archived = 0", [(int) $memberId]);

        $egyptianPrices = SeasonalPricingService::getPricingTable('egyptian');
        $foreignPrices = SeasonalPricingService::getPricingTable('foreign');

        return $this->view('Seasonal.Views.create', [
            'member'         => $member,
            'branches'       => $branches,
            'spouses'        => $spouses,
            'children'       => $children,
            'egyptianPrices' => $egyptianPrices,
            'foreignPrices'  => $foreignPrices,
        ]);
    }

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

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

        $nationalityType = in_array($data['nationality_type'] ?? '', ['egyptian', 'foreign'], true)
            ? $data['nationality_type'] : 'egyptian';
        $durationMonths = (int) ($data['duration_months'] ?? 6);
        $branchId = (int) ($data['branch_id'] ?? 0);
        $startDate = $data['start_date'] ?? date('Y-m-d');
        $hasQualification = !empty($data['has_qualification']);

        $validDurations = SeasonalPricingService::getValidDurations($nationalityType);
        if (!in_array($durationMonths, $validDurations, true)) {
            return $this->redirect("/members/{$memberId}/seasonal/create")->withError('مدة غير صالحة');
        }
        if ($branchId <= 0) {
            return $this->redirect("/members/{$memberId}/seasonal/create")->withError('الفرع مطلوب');
        }

        $endDate = date('Y-m-d', strtotime($startDate . " +{$durationMonths} months"));

        // Build items list
        $items = [];
        $memberAge = $member['date_of_birth'] ? (int) ((time() - strtotime($member['date_of_birth'])) / 31557600) : null;

        $items[] = [
            'person_type' => 'member',
            'name'        => $member['full_name_ar'],
            'age'         => $memberAge,
        ];

        // Add selected spouses
        $selectedSpouses = (array) ($data['spouses'] ?? []);
        foreach ($selectedSpouses as $spouseId) {
            $spouse = $db->selectOne("SELECT full_name_ar FROM spouses WHERE id = ? AND member_id = ? AND is_archived = 0", [(int) $spouseId, (int) $memberId]);
            if ($spouse) {
                $items[] = ['person_type' => 'spouse', 'name' => $spouse['full_name_ar'], 'age' => null];
            }
        }

        // Add selected children
        $selectedChildren = (array) ($data['children'] ?? []);
        foreach ($selectedChildren as $childId) {
            $child = $db->selectOne("SELECT full_name_ar, date_of_birth, TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) as age FROM children WHERE id = ? AND member_id = ? AND is_archived = 0", [(int) $childId, (int) $memberId]);
            if ($child) {
                $items[] = ['person_type' => 'child', 'name' => $child['full_name_ar'], 'age' => (int) $child['age']];
            }
        }

        // Calculate pricing
        $pricing = SeasonalPricingService::calculate($items, $nationalityType, $durationMonths, $hasQualification);

        // Create parent seasonal membership
        $parentSeasonal = SeasonalMembership::create([
            'member_id'        => (int) $memberId,
            'branch_id'        => $branchId,
            'nationality_type' => $nationalityType,
            'duration_months'  => $durationMonths,
            'person_type'      => 'member',
            'person_name'      => $member['full_name_ar'],
            'person_age'       => $memberAge,
            'age_category'     => ($memberAge && $memberAge >= 60) ? 'over_60' : null,
            'start_date'       => $startDate,
            'end_date'         => $endDate,
            'fee_amount'       => $pricing['items'][0]['base_price'],
            'currency'         => $pricing['currency'],
            'vat_amount'       => $pricing['vat_amount'],
            'discount_amount'  => $pricing['total_discount'],
            'discount_type'    => $pricing['family_discount']['type'] ?? ($hasQualification ? null : 'no_qualification'),
            'total_amount'     => $pricing['grand_total'],
            'status'           => 'pending_payment',
            'carnet_marking'   => 'موسمي',
            'includes_pool'    => 1,
            'notes'            => $data['notes'] ?? null,
        ]);

        $parentId = (int) $parentSeasonal->id;

        // Create child records for family members
        for ($i = 1; $i < count($items); $i++) {
            $item = $items[$i];
            $lineItem = $pricing['items'][$i];

            SeasonalMembership::create([
                'member_id'          => (int) $memberId,
                'parent_seasonal_id' => $parentId,
                'branch_id'          => $branchId,
                'nationality_type'   => $nationalityType,
                'duration_months'    => $durationMonths,
                'person_type'        => $item['person_type'],
                'person_name'        => $item['name'],
                'person_age'         => $item['age'],
                'age_category'       => $lineItem['age_category'],
                'start_date'         => $startDate,
                'end_date'           => $endDate,
                'fee_amount'         => $lineItem['base_price'],
                'currency'           => $pricing['currency'],
                'vat_amount'         => '0.00',
                'discount_amount'    => '0.00',
                'total_amount'       => $lineItem['base_price'],
                'status'             => 'pending_payment',
                'carnet_marking'     => 'موسمي',
                'includes_pool'      => 1,
            ]);
        }

        // Send collective payment request
        $breakdown = [];
        foreach ($pricing['items'] as $li) {
            $catLabel = SeasonalPricingService::getCategoryLabel($li['age_category'] ?? $li['person_type']);
            $breakdown[] = '📌 ' . $li['person_name'] . ' (' . $catLabel . '): ' . $li['base_price'] . ' ' . $pricing['currency'];
        }
        $breakdown[] = '═══════════════════════════';
        $breakdown[] = '💰 المجموع قبل الخصم: ' . $pricing['subtotal'] . ' ' . $pricing['currency'];
        if (bccomp($pricing['total_discount'], '0', 2) > 0) {
            $discLabel = $pricing['family_discount']['label'] ?? 'خصم عدم وجود مؤهل عالي';
            $breakdown[] = '🏷️ ' . $discLabel . ': -' . $pricing['total_discount'] . ' ' . $pricing['currency'];
        }
        $breakdown[] = '📊 ضريبة القيمة المضافة (' . $pricing['vat_rate'] . '%): ' . $pricing['vat_amount'] . ' ' . $pricing['currency'];
        $breakdown[] = '💵 الإجمالي: ' . $pricing['grand_total'] . ' ' . $pricing['currency'];

        $payResult = PaymentRequestService::createRequest([
            'member_id'           => (int) $memberId,
            'amount'              => $pricing['grand_total'],
            'payment_type'        => 'seasonal_fee',
            'related_entity_type' => 'seasonal_memberships',
            'related_entity_id'   => $parentId,
            'description_ar'      => 'عضوية موسمية ' . ($nationalityType === 'foreign' ? '(أجنبي)' : '(مصري)') . ' — ' . $durationMonths . ' شهر — من ' . $startDate,
            'notes'               => json_encode(['fee_breakdown' => $breakdown], JSON_UNESCAPED_UNICODE),
        ]);

        EventBus::dispatch('seasonal.created', [
            'member_id'        => (int) $memberId,
            'seasonal_id'      => $parentId,
            'nationality_type' => $nationalityType,
            'duration_months'  => $durationMonths,
            'total'            => $pricing['grand_total'],
            'currency'         => $pricing['currency'],
            'items_count'      => count($items),
        ]);

        $msg = 'تم إنشاء العضوية الموسمية (' . count($items) . ' فرد) — الإجمالي: ' . $pricing['grand_total'] . ' ' . $pricing['currency'];
        if ($payResult['success']) {
            $msg .= ' — طلب الخزينة: ' . $payResult['request_number'];
        }

        return $this->redirect("/members/{$memberId}")->withSuccess($msg);
    }

    public function pricePreview(Request $request): Response
    {
        $nationalityType = $request->get('nationality_type', 'egyptian');
        $durationMonths = (int) $request->get('duration_months', 6);
        $memberId = (int) $request->get('member_id', 0);
        $hasQualification = (bool) $request->get('has_qualification', 1);
        $selectedSpouses = explode(',', $request->get('spouses', ''));
        $selectedChildren = explode(',', $request->get('children', ''));

        $db = App::getInstance()->db();
        $member = $db->selectOne("SELECT full_name_ar, date_of_birth FROM members WHERE id = ? AND is_archived = 0", [$memberId]);
        if (!$member) return $this->json(['error' => 'member not found']);

        $memberAge = $member['date_of_birth'] ? (int) ((time() - strtotime($member['date_of_birth'])) / 31557600) : null;
        $items = [['person_type' => 'member', 'name' => $member['full_name_ar'], 'age' => $memberAge]];

        foreach (array_filter($selectedSpouses) as $sid) {
            $sp = $db->selectOne("SELECT full_name_ar FROM spouses WHERE id = ? AND member_id = ? AND is_archived = 0", [(int) $sid, $memberId]);
            if ($sp) $items[] = ['person_type' => 'spouse', 'name' => $sp['full_name_ar'], 'age' => null];
        }
        foreach (array_filter($selectedChildren) as $cid) {
            $ch = $db->selectOne("SELECT full_name_ar, TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) as age FROM children WHERE id = ? AND member_id = ? AND is_archived = 0", [(int) $cid, $memberId]);
            if ($ch) $items[] = ['person_type' => 'child', 'name' => $ch['full_name_ar'], 'age' => (int) $ch['age']];
        }

        $pricing = SeasonalPricingService::calculate($items, $nationalityType, $durationMonths, $hasQualification);

        return $this->json($pricing);
    }
}
