<?php
declare(strict_types=1);

namespace App\Modules\Treasury\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\Treasury\Services\TreasuryService;
use App\Modules\Treasury\Services\SessionService;
use App\Modules\Treasury\Services\CustodyService;
use App\Modules\Cashier\Services\PaymentRequestService;

class TreasuryController extends Controller
{
    public function dashboard(Request $request): Response
    {
        $this->authorize('treasury.view_dashboard');
        $employee = App::getInstance()->currentEmployee();
        $treasury = TreasuryService::getSubTreasury();

        if (!$treasury) {
            return $this->view('Treasury.Views.dashboard', [
                'error' => 'لم يتم تعريف الخزنة الفرعية',
                'stats' => null,
            ]);
        }

        $stats = TreasuryService::getDashboardStats((int) $treasury['id'], (int) $employee->id);

        return $this->view('Treasury.Views.dashboard', [
            'treasury' => $treasury,
            'stats'    => $stats,
            'error'    => null,
        ]);
    }

    public function queue(Request $request): Response
    {
        $this->authorize('treasury.collect_payment');
        $employee = App::getInstance()->currentEmployee();
        $treasury = TreasuryService::getSubTreasury();

        if (!$treasury) {
            return $this->redirect('/treasury')->withError('لم يتم تعريف الخزنة الفرعية');
        }

        $currentSession = SessionService::getCurrentSession((int) $treasury['id'], (int) $employee->id);
        if (!$currentSession) {
            return $this->redirect('/treasury')->withError('يجب فتح وردية أولاً قبل التحصيل');
        }

        $filters = [
            'status' => trim((string) $request->get('status', '')),
            'search' => trim((string) $request->get('search', '')),
        ];

        $requests = TreasuryService::getQueueForTreasury((int) $treasury['id'], $filters);

        return $this->view('Treasury.Views.queue', [
            'requests'       => $requests,
            'filters'        => $filters,
            'currentSession' => $currentSession,
            'treasury'       => $treasury,
        ]);
    }

    public function processForm(Request $request, string $id): Response
    {
        $this->authorize('treasury.collect_payment');
        $db = App::getInstance()->db();

        $pr = $db->selectOne(
            "SELECT pr.*, m.full_name_ar as member_name, m.form_number, m.membership_number, m.phone_mobile,
                    e.full_name_ar as requested_by_name
             FROM payment_requests pr
             LEFT JOIN members m ON m.id = pr.member_id
             LEFT JOIN employees e ON e.id = pr.requested_by
             WHERE pr.id = ? AND pr.is_voided = 0",
            [(int) $id]
        );

        if (!$pr) {
            return $this->redirect('/treasury/queue')->withError('طلب الدفع غير موجود');
        }
        if ($pr['status'] === 'completed') {
            return $this->redirect('/treasury/queue')->withError('طلب الدفع مكتمل بالفعل');
        }

        return $this->view('Treasury.Views.process', [
            'pr' => $pr,
        ]);
    }

    public function collect(Request $request, string $id): Response
    {
        $this->authorize('treasury.collect_payment');
        $employee = App::getInstance()->currentEmployee();
        $treasury = TreasuryService::getSubTreasury();

        if (!$treasury) {
            return $this->redirect('/treasury/queue')->withError('لم يتم تعريف الخزنة الفرعية');
        }

        $currentSession = SessionService::getCurrentSession((int) $treasury['id'], (int) $employee->id);
        if (!$currentSession) {
            return $this->redirect('/treasury')->withError('يجب فتح وردية أولاً');
        }

        $paymentMethod = trim((string) $request->post('payment_method', 'cash'));
        if ($paymentMethod === '') {
            return $this->redirect('/treasury/queue/' . $id)->withError('طريقة الدفع مطلوبة');
        }

        $result = TreasuryService::collectPayment((int) $currentSession['id'], (int) $id, $paymentMethod);

        if (!$result['success']) {
            return $this->redirect('/treasury/queue/' . $id)->withError($result['error']);
        }

        $receiptId = $result['receipt_id'] ?? null;
        $printParam = $receiptId ? '?print_receipt=' . $receiptId : '';

        return $this->redirect('/treasury/queue' . $printParam)->withSuccess(
            'تم تحصيل الدفعة — إيصال: ' . ($result['receipt_number'] ?? '')
        );
    }

    public function createAndCollect(Request $request): Response
    {
        $this->authorize('treasury.collect_payment');
        $employee = App::getInstance()->currentEmployee();
        $treasury = TreasuryService::getSubTreasury();

        if (!$treasury) {
            return $this->redirect('/treasury/queue')->withError('لم يتم تعريف الخزنة الفرعية');
        }

        $currentSession = SessionService::getCurrentSession((int) $treasury['id'], (int) $employee->id);
        if (!$currentSession) {
            return $this->redirect('/treasury')->withError('يجب فتح وردية أولاً');
        }

        $memberId = (int) $request->post('member_id', 0);
        $paymentType = trim((string) $request->post('payment_type', ''));
        $amount = trim((string) $request->post('amount', '0'));
        $paymentMethod = trim((string) $request->post('payment_method', 'cash'));
        $description = trim((string) $request->post('description_ar', ''));
        $entityType = trim((string) $request->post('related_entity_type', ''));
        $entityId = (int) $request->post('related_entity_id', 0);

        $errors = [];
        if ($memberId <= 0) {
            $errors[] = 'العضو مطلوب';
        }
        if ($paymentType === '') {
            $errors[] = 'نوع الدفعة مطلوب';
        }
        if (bccomp($amount, '0.01', 2) < 0) {
            $errors[] = 'المبلغ يجب أن يكون أكبر من صفر';
        }
        if ($paymentMethod === '') {
            $errors[] = 'طريقة الدفع مطلوبة';
        }

        if (!empty($errors)) {
            return $this->redirect('/treasury/queue')->withError(implode('، ', $errors));
        }

        $data = [
            'member_id'           => $memberId,
            'payment_type'        => $paymentType,
            'amount'              => $amount,
            'description_ar'      => $description,
            'related_entity_type' => $entityType !== '' ? $entityType : null,
            'related_entity_id'   => $entityId > 0 ? $entityId : null,
            'currency'            => 'EGP',
        ];

        $result = TreasuryService::createAndCollectPayment((int) $currentSession['id'], $data, $paymentMethod);

        if (!$result['success']) {
            return $this->redirect('/treasury/queue')->withError($result['error']);
        }

        $receiptId = $result['receipt_id'] ?? null;
        $printParam = $receiptId ? '?print_receipt=' . $receiptId : '';

        return $this->redirect('/treasury/queue' . $printParam)->withSuccess(
            'تم إنشاء وتحصيل الدفعة — إيصال: ' . ($result['receipt_number'] ?? '')
        );
    }

    public function custody(Request $request): Response
    {
        $this->authorize('treasury.view_custody');
        $employee = App::getInstance()->currentEmployee();
        $treasury = TreasuryService::getSubTreasury();

        if (!$treasury) {
            return $this->redirect('/treasury')->withError('لم يتم تعريف الخزنة الفرعية');
        }

        $log = CustodyService::getLog((int) $treasury['id'], (int) $employee->id);
        $balance = CustodyService::getCurrentBalance((int) $treasury['id'], (int) $employee->id);

        return $this->view('Treasury.Views.custody.index', [
            'log'      => $log,
            'balance'  => $balance,
            'treasury' => $treasury,
        ]);
    }
}
