<?php
declare(strict_types=1);

namespace App\Modules\Cashier\Controllers;

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

class DepositController extends Controller
{
    public function index(Request $request): Response
    {
        $this->authorize('cashier.manage_deposits');

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

        $deposits = DepositService::getDeposits($filters);

        return $this->view('Cashier.Views.deposits.index', [
            'deposits' => $deposits,
            'filters'  => $filters,
        ]);
    }

    public function create(Request $request): Response
    {
        $this->authorize('cashier.manage_deposits');
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $mainTreasury = TreasuryService::getMainTreasury();
        $custodyBalance = '0.00';
        if ($mainTreasury && $employee) {
            $custodyBalance = CustodyService::getCurrentBalance((int) $mainTreasury['id'], (int) $employee->id);
        }

        $bankAccounts = $db->select(
            "SELECT id, account_name_ar, bank_name_ar, account_number FROM bank_accounts WHERE is_active = 1 ORDER BY is_default DESC, account_name_ar"
        );

        return $this->view('Cashier.Views.deposits.create', [
            'bankAccounts'   => $bankAccounts,
            'custodyBalance' => $custodyBalance,
        ]);
    }

    public function store(Request $request): Response
    {
        $this->authorize('cashier.manage_deposits');

        $amount = trim((string) $request->post('amount', '0'));
        $bankAccountId = (int) $request->post('bank_account_id', 0);
        $depositDate = trim((string) $request->post('deposit_date', date('Y-m-d')));
        $bankReceiptSerial = trim((string) $request->post('bank_receipt_serial', ''));
        $notes = trim((string) $request->post('notes', ''));

        if (bccomp($amount, '0.01', 2) < 0) {
            return $this->redirect('/cashier/deposits/create')->withError('المبلغ يجب أن يكون أكبر من صفر');
        }
        if ($bankAccountId <= 0) {
            return $this->redirect('/cashier/deposits/create')->withError('يجب اختيار حساب بنكي');
        }
        if ($bankReceiptSerial === '') {
            return $this->redirect('/cashier/deposits/create')->withError('رقم إيصال البنك مطلوب');
        }

        // Handle file upload
        $bankReceiptPath = null;
        $uploadedFile = $_FILES['bank_receipt_image'] ?? null;
        if ($uploadedFile && $uploadedFile['error'] === UPLOAD_ERR_OK && $uploadedFile['size'] > 0) {
            $allowedTypes = ['image/jpeg', 'image/png', 'image/webp', 'application/pdf'];
            if (!in_array($uploadedFile['type'], $allowedTypes, true)) {
                return $this->redirect('/cashier/deposits/create')->withError('نوع الملف غير مسموح (JPG, PNG, WebP, PDF فقط)');
            }
            if ($uploadedFile['size'] > 5 * 1024 * 1024) {
                return $this->redirect('/cashier/deposits/create')->withError('حجم الملف يجب ألا يتجاوز 5 ميجابايت');
            }

            $uploadDir = App::getInstance()->basePath() . '/public/uploads/deposits/';
            if (!is_dir($uploadDir)) {
                mkdir($uploadDir, 0755, true);
            }
            $ext = pathinfo($uploadedFile['name'], PATHINFO_EXTENSION);
            $filename = 'dep_' . date('Ymd_His') . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
            move_uploaded_file($uploadedFile['tmp_name'], $uploadDir . $filename);
            $bankReceiptPath = 'uploads/deposits/' . $filename;
        }

        $result = DepositService::createDeposit([
            'amount'              => $amount,
            'bank_account_id'     => $bankAccountId,
            'deposit_date'        => $depositDate,
            'bank_receipt_serial' => $bankReceiptSerial,
            'bank_receipt_path'   => $bankReceiptPath,
            'notes'               => $notes !== '' ? $notes : null,
        ]);

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

        return $this->redirect('/cashier/deposits')->withSuccess(
            'تم تسجيل الإيداع — رقم: ' . $result['deposit_number'] . '. في انتظار تأكيد مدير الحسابات.'
        );
    }

    public function show(Request $request, string $id): Response
    {
        $this->authorize('cashier.manage_deposits');

        $deposit = DepositService::find((int) $id);
        if (!$deposit) {
            return $this->redirect('/cashier/deposits')->withError('الإيداع غير موجود');
        }

        return $this->view('Cashier.Views.deposits.show', [
            'deposit' => $deposit,
        ]);
    }

    public function confirm(Request $request, string $id): Response
    {
        $this->authorize('cashier.confirm_deposit');
        $employee = App::getInstance()->currentEmployee();

        $result = DepositService::confirmDeposit((int) $id, (int) $employee->id);

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

        return $this->redirect('/cashier/deposits')->withSuccess(
            'تم تأكيد الإيداع — المبلغ: ' . money($result['amount']) . '. تم إخلاء العهدة.'
        );
    }

    public function reject(Request $request, string $id): Response
    {
        $this->authorize('cashier.confirm_deposit');
        $employee = App::getInstance()->currentEmployee();

        $reason = trim((string) $request->post('reason', ''));
        if ($reason === '') {
            return $this->redirect('/cashier/deposits/' . $id)->withError('يجب إدخال سبب الرفض');
        }

        $result = DepositService::rejectDeposit((int) $id, (int) $employee->id, $reason);

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

        return $this->redirect('/cashier/deposits')->withSuccess('تم رفض الإيداع — المبلغ عاد لعهدة الخزنة');
    }
}
