<?php
declare(strict_types=1);

namespace App\Modules\Pricing\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\Pricing\Models\RegulatoryDiscount;
use App\Modules\Pricing\Services\RegulatoryDiscountService;

class RegulatoryDiscountController extends Controller
{
    public function index(Request $request): Response
    {
        $filters = [
            'search'           => trim((string) $request->get('q', '')),
            'is_active'        => $request->get('is_active', ''),
            'eligibility_type' => $request->get('eligibility_type', ''),
        ];
        $page = max(1, (int) $request->get('page', 1));
        $result = RegulatoryDiscount::search($filters, 25, $page);

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

        return $this->view('Pricing.Views.regulatory_discounts.index', [
            'rows'       => $result['data'],
            'pagination' => $result['pagination'],
            'filters'    => $filters,
            'branches'   => $branches,
        ]);
    }

    public function create(Request $request): Response
    {
        $db = App::getInstance()->db();
        $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_active = 1 ORDER BY name_ar");

        return $this->view('Pricing.Views.regulatory_discounts.form', [
            'discount' => null,
            'branches' => $branches,
            'tiers'    => [],
        ]);
    }

    public function store(Request $request): Response
    {
        $data = $this->extractFormData($request);

        $error = $this->validateData($data);
        if ($error) {
            return $this->redirect('/pricing/regulatory-discounts/create')->withError($error);
        }

        $db = App::getInstance()->db();
        $userId = session()->get('user_id');

        $insertData = $this->buildInsertArray($data);
        $insertData['created_by'] = $userId;
        $id = $db->insert('regulatory_discounts', $insertData);

        // Save group tiers if applicable
        if ($data['eligibility_type'] === 'group_membership') {
            $this->saveGroupTiers($db, (int) $id, $request);
        }

        return $this->redirect('/pricing/regulatory-discounts')->withSuccess('تم إضافة الخصم اللائحي بنجاح');
    }

    public function edit(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $discount = $db->selectOne("SELECT * FROM regulatory_discounts WHERE id = ?", [(int) $id]);
        if (!$discount) {
            return $this->redirect('/pricing/regulatory-discounts')->withError('الخصم غير موجود');
        }

        $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_active = 1 ORDER BY name_ar");
        $tiers = $db->select("SELECT * FROM regulatory_discount_group_tiers WHERE regulatory_discount_id = ? ORDER BY min_quantity", [(int) $id]);

        return $this->view('Pricing.Views.regulatory_discounts.form', [
            'discount' => $discount,
            'branches' => $branches,
            'tiers'    => $tiers,
        ]);
    }

    public function update(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $discount = $db->selectOne("SELECT * FROM regulatory_discounts WHERE id = ?", [(int) $id]);
        if (!$discount) {
            return $this->redirect('/pricing/regulatory-discounts')->withError('الخصم غير موجود');
        }

        $data = $this->extractFormData($request);
        $data['is_active'] = (int) $request->post('is_active', 1);

        $error = $this->validateData($data);
        if ($error) {
            return $this->redirect("/pricing/regulatory-discounts/{$id}/edit")->withError($error);
        }

        $userId = session()->get('user_id');
        $updateData = $this->buildInsertArray($data);
        $updateData['is_active'] = $data['is_active'];
        $updateData['updated_by'] = $userId;

        $db->update('regulatory_discounts', $updateData, 'id = ?', [(int) $id]);

        if ($data['eligibility_type'] === 'group_membership') {
            $db->delete('regulatory_discount_group_tiers', 'regulatory_discount_id = ?', [(int) $id]);
            $this->saveGroupTiers($db, (int) $id, $request);
        }

        return $this->redirect('/pricing/regulatory-discounts')->withSuccess('تم تحديث الخصم اللائحي');
    }

    public function toggleActive(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $discount = $db->selectOne("SELECT * FROM regulatory_discounts WHERE id = ?", [(int) $id]);
        if (!$discount) {
            return $this->redirect('/pricing/regulatory-discounts')->withError('الخصم غير موجود');
        }

        $newActive = $discount['is_active'] ? 0 : 1;
        $db->update('regulatory_discounts', [
            'is_active'  => $newActive,
            'updated_at' => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $id]);

        return $this->redirect('/pricing/regulatory-discounts')->withSuccess($newActive ? 'تم تفعيل الخصم' : 'تم تعطيل الخصم');
    }

    public function checkEligibility(Request $request): Response
    {
        $context = [
            'target_branch_id'          => (int) $request->post('target_branch_id', 0),
            'source_branch_id'          => (int) $request->post('source_branch_id', 0),
            'is_government_employee'    => (bool) $request->post('is_government_employee', false),
            'is_ministry_youth_employee'=> (bool) $request->post('is_ministry_youth_employee', false),
            'is_board_of_trustees'      => (bool) $request->post('is_board_of_trustees', false),
            'is_club_employee'          => (bool) $request->post('is_club_employee', false),
            'employee_years'            => (int) $request->post('employee_years', 0),
            'group_quantity'            => (int) $request->post('group_quantity', 0),
            'membership_fee'            => (string) $request->post('membership_fee', '0'),
        ];

        $results = RegulatoryDiscountService::evaluateEligibility($context);
        $best = RegulatoryDiscountService::getBestDiscount($context);

        return $this->json([
            'success'    => true,
            'applicable' => $results,
            'best'       => $best,
        ]);
    }

    public function applications(Request $request): Response
    {
        $db = App::getInstance()->db();
        $page = max(1, (int) $request->get('page', 1));
        $perPage = 25;
        $offset = ($page - 1) * $perPage;
        $statusFilter = $request->get('status', '');

        $where = "1=1";
        $params = [];
        if ($statusFilter !== '') {
            $where .= " AND rda.status = ?";
            $params[] = $statusFilter;
        }

        $total = (int) $db->selectOne("SELECT COUNT(*) as cnt FROM regulatory_discount_applications rda WHERE {$where}", $params)['cnt'];
        $rows = $db->select(
            "SELECT rda.*, rd.name_ar as rule_name, rd.article_number FROM regulatory_discount_applications rda LEFT JOIN regulatory_discounts rd ON rd.id = rda.regulatory_discount_id WHERE {$where} ORDER BY rda.created_at DESC LIMIT {$perPage} OFFSET {$offset}",
            $params
        );

        return $this->view('Pricing.Views.regulatory_discounts.applications', [
            'rows'       => $rows,
            'pagination' => ['current_page' => $page, 'last_page' => (int) ceil($total / $perPage), 'total' => $total],
            'statusFilter' => $statusFilter,
        ]);
    }

    public function approveApplication(Request $request, string $id): Response
    {
        $userId = (int) session()->get('user_id');
        $success = RegulatoryDiscountService::approveApplication((int) $id, $userId);

        if (!$success) {
            return $this->redirect('/pricing/regulatory-discounts/applications')->withError('لا يمكن اعتماد هذا الطلب');
        }

        return $this->redirect('/pricing/regulatory-discounts/applications')->withSuccess('تم اعتماد طلب الخصم');
    }

    public function rejectApplication(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $app = $db->selectOne("SELECT * FROM regulatory_discount_applications WHERE id = ? AND status = 'pending'", [(int) $id]);
        if (!$app) {
            return $this->redirect('/pricing/regulatory-discounts/applications')->withError('الطلب غير موجود أو ليس معلقاً');
        }

        $reason = trim((string) $request->post('rejection_reason', ''));
        $db->update('regulatory_discount_applications', [
            'status'           => 'rejected',
            'rejection_reason' => $reason ?: null,
            'approved_by'      => session()->get('user_id'),
            'approved_at'      => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $id]);

        return $this->redirect('/pricing/regulatory-discounts/applications')->withSuccess('تم رفض طلب الخصم');
    }

    private function extractFormData(Request $request): array
    {
        return [
            'article_number'           => trim((string) $request->post('article_number', '')),
            'name_ar'                  => trim((string) $request->post('name_ar', '')),
            'name_en'                  => trim((string) $request->post('name_en', '')) ?: null,
            'description'              => trim((string) $request->post('description', '')) ?: null,
            'discount_percentage'      => trim((string) $request->post('discount_percentage', '0')),
            'max_discount_percentage'  => trim((string) $request->post('max_discount_percentage', '')) ?: null,
            'eligibility_type'         => $request->post('eligibility_type', 'government_employee'),
            'source_branch_id'         => ((int) $request->post('source_branch_id', 0)) ?: null,
            'target_branch_id'         => ((int) $request->post('target_branch_id', 0)) ?: null,
            'min_service_years'        => ((int) $request->post('min_service_years', 0)) ?: null,
            'allows_installment'       => (int) $request->post('allows_installment', 0),
            'installment_max_years'    => ((int) $request->post('installment_max_years', 0)) ?: null,
            'installment_interest_rate'=> trim((string) $request->post('installment_interest_rate', '0')),
            'applies_to'               => $request->post('applies_to', 'membership_fee'),
            'effective_from'           => trim((string) $request->post('effective_from', '')) ?: null,
            'effective_to'             => trim((string) $request->post('effective_to', '')) ?: null,
            'board_decision_number'    => trim((string) $request->post('board_decision_number', '')) ?: null,
            'board_decision_date'      => trim((string) $request->post('board_decision_date', '')) ?: null,
            'notes'                    => trim((string) $request->post('notes', '')) ?: null,
        ];
    }

    private function validateData(array $data): ?string
    {
        if ($data['name_ar'] === '') {
            return 'اسم الخصم مطلوب';
        }
        if ($data['article_number'] === '') {
            return 'رقم المادة مطلوب';
        }

        $validTypes = ['cross_branch_member', 'government_employee', 'ministry_youth_employee', 'board_of_trustees', 'club_employee', 'group_membership'];
        if (!in_array($data['eligibility_type'], $validTypes, true)) {
            return 'نوع الاستحقاق غير صالح';
        }

        if ($data['eligibility_type'] !== 'group_membership') {
            $pct = $data['discount_percentage'];
            if (bccomp($pct, '0', 2) <= 0 || bccomp($pct, '100', 2) > 0) {
                return 'نسبة الخصم يجب أن تكون بين 0.01% و 100%';
            }
        }

        if ($data['eligibility_type'] === 'cross_branch_member') {
            if (!$data['source_branch_id'] || !$data['target_branch_id']) {
                return 'يجب تحديد فرع المصدر والفرع المستهدف لخصم عبر الفروع';
            }
        }

        return null;
    }

    private function buildInsertArray(array $data): array
    {
        return [
            'article_number'            => $data['article_number'],
            'name_ar'                   => $data['name_ar'],
            'name_en'                   => $data['name_en'],
            'description'               => $data['description'],
            'discount_percentage'       => $data['discount_percentage'],
            'max_discount_percentage'   => $data['max_discount_percentage'],
            'eligibility_type'          => $data['eligibility_type'],
            'source_branch_id'          => $data['source_branch_id'],
            'target_branch_id'          => $data['target_branch_id'],
            'min_service_years'         => $data['min_service_years'],
            'allows_installment'        => $data['allows_installment'],
            'installment_max_years'     => $data['installment_max_years'],
            'installment_interest_rate' => $data['installment_interest_rate'],
            'applies_to'                => $data['applies_to'],
            'effective_from'            => $data['effective_from'],
            'effective_to'              => $data['effective_to'],
            'board_decision_number'     => $data['board_decision_number'],
            'board_decision_date'       => $data['board_decision_date'],
            'notes'                     => $data['notes'],
        ];
    }

    private function saveGroupTiers(\App\Core\Database $db, int $discountId, Request $request): void
    {
        $mins = $request->post('tier_min', []);
        $maxs = $request->post('tier_max', []);
        $pcts = $request->post('tier_pct', []);

        if (!is_array($mins)) return;

        for ($i = 0; $i < count($mins); $i++) {
            $min = (int) ($mins[$i] ?? 0);
            $max = !empty($maxs[$i]) ? (int) $maxs[$i] : null;
            $pct = trim((string) ($pcts[$i] ?? '0'));

            if ($min <= 0 || bccomp($pct, '0', 2) <= 0) continue;

            $db->insert('regulatory_discount_group_tiers', [
                'regulatory_discount_id' => $discountId,
                'min_quantity'           => $min,
                'max_quantity'           => $max,
                'discount_percentage'    => $pct,
            ]);
        }
    }
}
