<?php
declare(strict_types=1);

namespace App\Modules\AcademyContracts\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\AcademyContracts\Models\AcademyContract;
use App\Modules\AcademyContracts\Models\AcademySettlement;
use App\Modules\AcademyContracts\Services\AcademyContractService;
use App\Modules\Academies\Models\Academy;

class AcademyContractController extends Controller
{
    /**
     * List all contracts with filters and pagination.
     */
    public function index(Request $request): Response
    {
        $filters = [
            'q'             => trim((string) $request->get('q', '')),
            'status'        => trim((string) $request->get('status', '')),
            'academy_id'    => trim((string) $request->get('academy_id', '')),
            'contract_type' => trim((string) $request->get('contract_type', '')),
        ];

        $page = max(1, (int) $request->get('page', 1));
        $result = AcademyContract::search($filters, 25, $page);

        return $this->view('AcademyContracts.Views.index', [
            'contracts'     => $result['data'],
            'pagination'    => $result['pagination'],
            'filters'       => $filters,
            'statuses'      => AcademyContract::getStatuses(),
            'contractTypes' => AcademyContract::getContractTypes(),
            'academies'     => Academy::allActive(),
        ]);
    }

    /**
     * Show the create contract form.
     */
    public function create(Request $request): Response
    {
        return $this->view('AcademyContracts.Views.create', [
            'contractTypes' => AcademyContract::getContractTypes(),
            'academies'     => Academy::allActive(),
        ]);
    }

    /**
     * Validate and store a new contract.
     */
    public function store(Request $request): Response
    {
        $academyId              = (int) $request->post('academy_id', 0);
        $contractType           = trim((string) $request->post('contract_type', 'revenue_share'));
        $startDate              = trim((string) $request->post('start_date', ''));
        $endDate                = trim((string) $request->post('end_date', ''));
        $minimumRevenueGuarantee = (float) $request->post('minimum_revenue_guarantee', 0);
        $clubCommissionPct      = (float) $request->post('club_commission_pct', 0);
        $academySharePct        = (float) $request->post('academy_share_pct', 0);
        $fixedMonthlyRent       = (float) $request->post('fixed_monthly_rent', 0);
        $depositAmount          = (float) $request->post('deposit_amount', 0);
        $depositStatus          = trim((string) $request->post('deposit_status', 'pending'));
        $settlementDay          = (int) $request->post('settlement_day', 5);
        $gracePeriodDays        = (int) $request->post('grace_period_days', 7);
        $penaltyRatePct         = (float) $request->post('penalty_rate_pct', 0);
        $autoRenew              = (int) $request->post('auto_renew', 0);
        $renewalNoticeDays      = (int) $request->post('renewal_notice_days', 30);
        $notes                  = trim((string) $request->post('notes', ''));

        // Validation
        $errors = [];

        if ($academyId <= 0) {
            $errors[] = 'الأكاديمية مطلوبة';
        } else {
            $academy = Academy::find($academyId);
            if (!$academy) {
                $errors[] = 'الأكاديمية غير موجودة';
            }
        }

        if ($startDate === '') {
            $errors[] = 'تاريخ البداية مطلوب';
        }
        if ($endDate === '') {
            $errors[] = 'تاريخ النهاية مطلوب';
        }
        if ($startDate !== '' && $endDate !== '' && $startDate >= $endDate) {
            $errors[] = 'تاريخ البداية يجب أن يكون قبل تاريخ النهاية';
        }

        if ($minimumRevenueGuarantee < 0) {
            $errors[] = 'الحد الأدنى للإيرادات يجب أن يكون صفر أو أكثر';
        }

        if (!array_key_exists($contractType, AcademyContract::getContractTypes())) {
            $errors[] = 'نوع العقد غير صالح';
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
            $session->flash('_old_input', $request->all());
            return $this->redirect('/academy-contracts/create');
        }

        // Auto-generate contract number
        $contractNumber = AcademyContractService::generateContractNumber();

        $contract = AcademyContract::create([
            'contract_number'           => $contractNumber,
            'academy_id'                => $academyId,
            'contract_type'             => $contractType,
            'start_date'                => $startDate,
            'end_date'                  => $endDate,
            'minimum_revenue_guarantee' => $minimumRevenueGuarantee,
            'club_commission_pct'       => $clubCommissionPct,
            'academy_share_pct'         => $academySharePct,
            'fixed_monthly_rent'        => $fixedMonthlyRent,
            'deposit_amount'            => $depositAmount,
            'deposit_status'            => $depositStatus,
            'settlement_day'            => $settlementDay,
            'grace_period_days'         => $gracePeriodDays,
            'penalty_rate_pct'          => $penaltyRatePct,
            'auto_renew'                => $autoRenew ? 1 : 0,
            'renewal_notice_days'       => $renewalNoticeDays,
            'status'                    => 'draft',
            'notes'                     => $notes ?: null,
        ]);

        // Handle contract document upload
        if (isset($_FILES['contract_document']) && $_FILES['contract_document']['error'] === UPLOAD_ERR_OK) {
            $file = $_FILES['contract_document'];
            if ($file['type'] !== 'application/pdf') {
                return $this->redirect('/academy-contracts/' . $contract->id)->withError('يجب أن يكون المستند بصيغة PDF');
            }
            if ($file['size'] > 10 * 1024 * 1024) {
                return $this->redirect('/academy-contracts/' . $contract->id)->withError('حجم الملف أكبر من 10 ميجا');
            }
            $uploadDir = App::getInstance()->storagePath() . '/uploads/academy_contracts';
            if (!is_dir($uploadDir)) {
                mkdir($uploadDir, 0755, true);
            }
            $filename = 'contract_' . $contract->id . '_' . time() . '.pdf';
            move_uploaded_file($file['tmp_name'], $uploadDir . '/' . $filename);
            $contract->update(['contract_document_path' => 'uploads/academy_contracts/' . $filename]);
        }

        return $this->redirect('/academy-contracts/' . $contract->id)->withSuccess('تم إنشاء العقد بنجاح');
    }

    /**
     * Show contract detail page.
     */
    public function show(Request $request, string $id): Response
    {
        $contract = AcademyContract::find((int) $id);
        if (!$contract) {
            return $this->redirect('/academy-contracts')->withError('العقد غير موجود');
        }

        $academy = Academy::find((int) $contract->academy_id);

        // Get settlements for this contract
        $db = App::getInstance()->db();
        $settlements = $db->select(
            "SELECT * FROM academy_settlements WHERE contract_id = ? ORDER BY period_month DESC LIMIT 12",
            [(int) $id]
        );

        return $this->view('AcademyContracts.Views.show', [
            'contract'    => $contract,
            'academy'     => $academy,
            'settlements' => $settlements,
        ]);
    }

    /**
     * Show edit form for a contract.
     */
    public function edit(Request $request, string $id): Response
    {
        $contract = AcademyContract::find((int) $id);
        if (!$contract) {
            return $this->redirect('/academy-contracts')->withError('العقد غير موجود');
        }

        return $this->view('AcademyContracts.Views.edit', [
            'contract'      => $contract,
            'contractTypes' => AcademyContract::getContractTypes(),
            'academies'     => Academy::allActive(),
        ]);
    }

    /**
     * Validate and update an existing contract.
     */
    public function update(Request $request, string $id): Response
    {
        $contract = AcademyContract::find((int) $id);
        if (!$contract) {
            return $this->redirect('/academy-contracts')->withError('العقد غير موجود');
        }

        $academyId              = (int) $request->post('academy_id', 0);
        $contractType           = trim((string) $request->post('contract_type', 'revenue_share'));
        $startDate              = trim((string) $request->post('start_date', ''));
        $endDate                = trim((string) $request->post('end_date', ''));
        $minimumRevenueGuarantee = (float) $request->post('minimum_revenue_guarantee', 0);
        $clubCommissionPct      = (float) $request->post('club_commission_pct', 0);
        $academySharePct        = (float) $request->post('academy_share_pct', 0);
        $fixedMonthlyRent       = (float) $request->post('fixed_monthly_rent', 0);
        $depositAmount          = (float) $request->post('deposit_amount', 0);
        $depositStatus          = trim((string) $request->post('deposit_status', 'pending'));
        $settlementDay          = (int) $request->post('settlement_day', 5);
        $gracePeriodDays        = (int) $request->post('grace_period_days', 7);
        $penaltyRatePct         = (float) $request->post('penalty_rate_pct', 0);
        $autoRenew              = (int) $request->post('auto_renew', 0);
        $renewalNoticeDays      = (int) $request->post('renewal_notice_days', 30);
        $notes                  = trim((string) $request->post('notes', ''));

        // Validation
        $errors = [];

        if ($academyId <= 0) {
            $errors[] = 'الأكاديمية مطلوبة';
        } else {
            $academy = Academy::find($academyId);
            if (!$academy) {
                $errors[] = 'الأكاديمية غير موجودة';
            }
        }

        if ($startDate === '') {
            $errors[] = 'تاريخ البداية مطلوب';
        }
        if ($endDate === '') {
            $errors[] = 'تاريخ النهاية مطلوب';
        }
        if ($startDate !== '' && $endDate !== '' && $startDate >= $endDate) {
            $errors[] = 'تاريخ البداية يجب أن يكون قبل تاريخ النهاية';
        }

        if ($minimumRevenueGuarantee < 0) {
            $errors[] = 'الحد الأدنى للإيرادات يجب أن يكون صفر أو أكثر';
        }

        if (!array_key_exists($contractType, AcademyContract::getContractTypes())) {
            $errors[] = 'نوع العقد غير صالح';
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
            $session->flash('_old_input', $request->all());
            return $this->redirect('/academy-contracts/' . $id . '/edit');
        }

        $contract->update([
            'academy_id'                => $academyId,
            'contract_type'             => $contractType,
            'start_date'                => $startDate,
            'end_date'                  => $endDate,
            'minimum_revenue_guarantee' => $minimumRevenueGuarantee,
            'club_commission_pct'       => $clubCommissionPct,
            'academy_share_pct'         => $academySharePct,
            'fixed_monthly_rent'        => $fixedMonthlyRent,
            'deposit_amount'            => $depositAmount,
            'deposit_status'            => $depositStatus,
            'settlement_day'            => $settlementDay,
            'grace_period_days'         => $gracePeriodDays,
            'penalty_rate_pct'          => $penaltyRatePct,
            'auto_renew'                => $autoRenew ? 1 : 0,
            'renewal_notice_days'       => $renewalNoticeDays,
            'notes'                     => $notes ?: null,
        ]);

        // Handle contract document upload
        if (isset($_FILES['contract_document']) && $_FILES['contract_document']['error'] === UPLOAD_ERR_OK) {
            $file = $_FILES['contract_document'];
            if ($file['type'] !== 'application/pdf') {
                return $this->redirect('/academy-contracts/' . $id)->withError('يجب أن يكون المستند بصيغة PDF');
            }
            if ($file['size'] > 10 * 1024 * 1024) {
                return $this->redirect('/academy-contracts/' . $id)->withError('حجم الملف أكبر من 10 ميجا');
            }
            $uploadDir = App::getInstance()->storagePath() . '/uploads/academy_contracts';
            if (!is_dir($uploadDir)) {
                mkdir($uploadDir, 0755, true);
            }
            $filename = 'contract_' . $contract->id . '_' . time() . '.pdf';
            move_uploaded_file($file['tmp_name'], $uploadDir . '/' . $filename);
            $contract->update(['contract_document_path' => 'uploads/academy_contracts/' . $filename]);
        }

        return $this->redirect('/academy-contracts/' . $id)->withSuccess('تم تحديث العقد بنجاح');
    }

    /**
     * Activate a contract.
     */
    public function activate(Request $request, string $id): Response
    {
        $contract = AcademyContract::find((int) $id);
        if (!$contract) {
            return $this->redirect('/academy-contracts')->withError('العقد غير موجود');
        }

        $session = App::getInstance()->session();
        $currentUser = $session->get('employee_id', 0);

        AcademyContractService::activate((int) $id, (int) $currentUser);

        return $this->redirect('/academy-contracts/' . $id)->withSuccess('تم تفعيل العقد بنجاح');
    }

    /**
     * Terminate a contract.
     */
    public function terminate(Request $request, string $id): Response
    {
        $contract = AcademyContract::find((int) $id);
        if (!$contract) {
            return $this->redirect('/academy-contracts')->withError('العقد غير موجود');
        }

        $reason = trim((string) $request->post('termination_reason', ''));
        if ($reason === '') {
            $session = App::getInstance()->session();
            $session->flash('_alerts', [['type' => 'error', 'message' => 'سبب الإنهاء مطلوب']]);
            return $this->redirect('/academy-contracts/' . $id);
        }

        $session = App::getInstance()->session();
        $currentUser = $session->get('employee_id', 0);

        AcademyContractService::terminate((int) $id, (int) $currentUser, $reason);

        return $this->redirect('/academy-contracts/' . $id)->withSuccess('تم إنهاء العقد بنجاح');
    }
}
