<?php
declare(strict_types=1);

namespace App\Modules\Installments\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\Installments\Services\ChequeService;

class ChequeController extends Controller
{
    public function index(Request $request, string $planId): Response
    {
        $this->authorize('installment.view');

        $db = App::getInstance()->db();

        $plan = $db->selectOne(
            "SELECT ip.*, m.full_name_ar as member_name, m.membership_number, m.status as member_status, m.form_number
             FROM installment_plans ip
             JOIN members m ON m.id = ip.member_id
             WHERE ip.id = ? AND ip.status = 'active'",
            [(int) $planId]
        );

        if (!$plan) {
            return $this->redirect('/installments')->withError('خطة التقسيط غير موجودة أو غير نشطة');
        }

        $cheques = $db->select(
            "SELECT ic.*, e.full_name_ar as uploaded_by_name
             FROM installment_cheques ic
             LEFT JOIN employees e ON e.id = ic.uploaded_by
             WHERE ic.installment_plan_id = ?
             ORDER BY ic.cheque_date ASC",
            [(int) $planId]
        );

        $requiredCount = (int) $plan['number_of_months'];
        $uploadedCount = count($cheques);
        $remainingCount = max(0, $requiredCount - $uploadedCount);
        $allSubmitted = $remainingCount === 0;

        return $this->view('Installments.Views.cheques', [
            'plan'           => $plan,
            'cheques'        => $cheques,
            'requiredCount'  => $requiredCount,
            'uploadedCount'  => $uploadedCount,
            'remainingCount' => $remainingCount,
            'allSubmitted'   => $allSubmitted,
        ]);
    }

    public function store(Request $request, string $planId): Response
    {
        $this->authorize('installment.create_plan');

        $db = App::getInstance()->db();

        $plan = $db->selectOne(
            "SELECT id, member_id, number_of_months FROM installment_plans WHERE id = ? AND status = 'active'",
            [(int) $planId]
        );

        if (!$plan) {
            return $this->redirect('/installments')->withError('خطة التقسيط غير موجودة');
        }

        $chequeNumber = trim((string) $request->post('cheque_number', ''));
        $bankName = trim((string) $request->post('bank_name', ''));
        $chequeDate = trim((string) $request->post('cheque_date', ''));
        $chequeAmount = trim((string) $request->post('cheque_amount', ''));
        $notes = trim((string) $request->post('notes', ''));

        $errors = [];
        if ($chequeNumber === '') {
            $errors[] = 'رقم الشيك مطلوب';
        } elseif (mb_strlen($chequeNumber) > 50) {
            $errors[] = 'رقم الشيك يجب ألا يتجاوز 50 حرف';
        }
        if ($bankName === '') {
            $errors[] = 'اسم البنك مطلوب';
        } elseif (mb_strlen($bankName) > 200) {
            $errors[] = 'اسم البنك يجب ألا يتجاوز 200 حرف';
        }
        if ($chequeDate === '') {
            $errors[] = 'تاريخ الشيك مطلوب';
        }
        if ($chequeAmount === '' || (float) $chequeAmount <= 0) {
            $errors[] = 'مبلغ الشيك مطلوب ويجب أن يكون أكبر من صفر';
        }

        // Check uploaded count
        $currentCount = (int) $db->selectOne(
            "SELECT COUNT(*) as cnt FROM installment_cheques WHERE installment_plan_id = ?",
            [(int) $planId]
        )['cnt'];

        if ($currentCount >= (int) $plan['number_of_months']) {
            return $this->redirect("/installments/{$planId}/cheques")->withError('تم رفع جميع الشيكات المطلوبة بالفعل');
        }

        // File upload validation
        $file = $_FILES['scan_file'] ?? null;
        if (!$file || $file['error'] !== UPLOAD_ERR_OK) {
            $errors[] = 'صورة/مسح الشيك مطلوبة';
        } else {
            $allowedMimes = ['image/jpeg', 'image/png', 'image/webp', 'application/pdf'];
            $finfo = new \finfo(FILEINFO_MIME_TYPE);
            $detectedMime = $finfo->file($file['tmp_name']);
            if (!in_array($detectedMime, $allowedMimes, true)) {
                $errors[] = 'نوع الملف غير مسموح (يُقبل: JPG, PNG, WebP, PDF)';
            }
            if ($file['size'] > 10 * 1024 * 1024) {
                $errors[] = 'حجم الملف يتجاوز الحد الأقصى (10 ميجابايت)';
            }
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $alerts = array_map(fn($msg) => ['type' => 'error', 'message' => $msg], $errors);
            $session->flash('_alerts', $alerts);
            $session->flash('_old_input', $request->all());
            return $this->redirect("/installments/{$planId}/cheques");
        }

        // Store the file
        $uploadDir = App::getInstance()->basePath() . '/storage/uploads/cheques/';
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }

        $ext = pathinfo($file['name'], PATHINFO_EXTENSION) ?: 'jpg';
        $storedFilename = 'chq_' . $planId . '_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
        $destination = $uploadDir . $storedFilename;

        if (!move_uploaded_file($file['tmp_name'], $destination)) {
            return $this->redirect("/installments/{$planId}/cheques")->withError('فشل في حفظ الملف');
        }

        $employeeId = App::getInstance()->session()->get('employee_id');

        $db->insert('installment_cheques', [
            'installment_plan_id' => (int) $planId,
            'cheque_number'       => $chequeNumber,
            'bank_name'           => $bankName,
            'cheque_date'         => $chequeDate,
            'cheque_amount'       => (float) $chequeAmount,
            'scan_path'           => 'storage/uploads/cheques/' . $storedFilename,
            'scan_original_name'  => $file['name'],
            'uploaded_by'         => $employeeId ? (int) $employeeId : null,
            'notes'               => $notes ?: null,
            'created_at'          => date('Y-m-d H:i:s'),
            'updated_at'          => date('Y-m-d H:i:s'),
        ]);

        // Check if all cheques now submitted → activate member
        if (ChequeService::allChequesSubmitted((int) $planId)) {
            $result = ChequeService::activateMemberAfterCheques((int) $planId);
            if ($result['success'] && !($result['already_active'] ?? false)) {
                return $this->redirect("/installments/{$planId}/cheques")
                    ->withSuccess('تم رفع الشيك وتفعيل العضوية بنجاح — رقم العضوية: ' . ($result['membership_number'] ?? ''));
            }
        }

        $remaining = (int) $plan['number_of_months'] - ($currentCount + 1);
        $msg = 'تم رفع الشيك بنجاح';
        if ($remaining > 0) {
            $msg .= " — المتبقي: {$remaining} شيك";
        }

        return $this->redirect("/installments/{$planId}/cheques")->withSuccess($msg);
    }
}
