<?php
declare(strict_types=1);

namespace App\Modules\Accounting\Controllers;

use App\Core\Controller;
use App\Core\App;
use App\Core\Response;
use App\Modules\Accounting\Models\BankAccount;
use App\Modules\Accounting\Models\Account;

class BankAccountController extends Controller
{
    public function index(): Response
    {
        $this->authorize('accounting.bank_account.view');

        $accounts = BankAccount::query()
            ->where('is_archived', '=', 0)
            ->orderBy('account_name_ar', 'ASC')
            ->get();

        return $this->view('Accounting/Views/bank_accounts/index', [
            'accounts' => $accounts,
        ]);
    }

    public function create(): Response
    {
        $this->authorize('accounting.bank_account.manage');

        $glAccounts = Account::query()
            ->where('is_archived', '=', 0)
            ->where('is_bank_account', '=', 1)
            ->where('is_header', '=', 0)
            ->orderBy('account_code', 'ASC')
            ->get();

        if (empty($glAccounts)) {
            $glAccounts = Account::query()
                ->where('is_archived', '=', 0)
                ->where('account_code', 'LIKE', '1102%')
                ->where('is_header', '=', 0)
                ->orderBy('account_code', 'ASC')
                ->get();
        }

        return $this->view('Accounting/Views/bank_accounts/create', [
            'gl_accounts' => $glAccounts,
        ]);
    }

    public function store(): Response
    {
        $this->authorize('accounting.bank_account.manage');

        $data = $this->validate($_POST, [
            'account_name_ar' => 'required',
            'bank_name_ar'    => 'required',
            'account_number'  => 'required',
        ]);

        $isDefault = (int) ($_POST['is_default'] ?? 0);
        if ($isDefault) {
            $db = App::getInstance()->db();
            $db->execute("UPDATE bank_accounts SET is_default = 0 WHERE is_default = 1");
        }

        $ba = BankAccount::create([
            'account_name_ar' => $data['account_name_ar'],
            'account_name_en' => $_POST['account_name_en'] ?? '',
            'bank_name_ar'    => $data['bank_name_ar'],
            'bank_name_en'    => $_POST['bank_name_en'] ?? null,
            'account_number'  => $data['account_number'],
            'iban'            => $_POST['iban'] ?? null,
            'swift_code'      => $_POST['swift_code'] ?? null,
            'branch_name'     => $_POST['branch_name'] ?? null,
            'currency'        => $_POST['currency'] ?? 'EGP',
            'gl_account_id'   => !empty($_POST['gl_account_id']) ? (int) $_POST['gl_account_id'] : null,
            'opening_balance' => $_POST['opening_balance'] ?? '0.00',
            'current_balance' => $_POST['opening_balance'] ?? '0.00',
            'is_default'      => $isDefault,
            'is_active'       => 1,
            'notes'           => $_POST['notes'] ?? null,
        ]);

        // Link GL account
        if (!empty($_POST['gl_account_id'])) {
            $db = App::getInstance()->db();
            $db->update('chart_of_accounts', [
                'is_bank_account' => 1,
                'bank_account_id' => $ba->id,
            ], '`id` = ?', [(int) $_POST['gl_account_id']]);
        }

        $session = App::getInstance()->session();
        $session->flash('_alerts', [['type' => 'success', 'message' => 'تم إنشاء الحساب البنكي بنجاح']]);
        return $this->redirect('/accounting/bank-accounts');
    }

    public function edit(int $id): Response
    {
        $this->authorize('accounting.bank_account.manage');

        $account = BankAccount::findOrFail($id);

        $glAccounts = Account::query()
            ->where('is_archived', '=', 0)
            ->where('account_type', '=', 'asset')
            ->where('is_header', '=', 0)
            ->orderBy('account_code', 'ASC')
            ->get();

        return $this->view('Accounting/Views/bank_accounts/edit', [
            'account'     => $account->toArray(),
            'gl_accounts' => $glAccounts,
        ]);
    }

    public function update(int $id): Response
    {
        $this->authorize('accounting.bank_account.manage');

        $account = BankAccount::findOrFail($id);

        $data = $this->validate($_POST, [
            'account_name_ar' => 'required',
            'bank_name_ar'    => 'required',
        ]);

        $account->update([
            'account_name_ar' => $data['account_name_ar'],
            'account_name_en' => $_POST['account_name_en'] ?? '',
            'bank_name_ar'    => $data['bank_name_ar'],
            'bank_name_en'    => $_POST['bank_name_en'] ?? null,
            'iban'            => $_POST['iban'] ?? null,
            'swift_code'      => $_POST['swift_code'] ?? null,
            'branch_name'     => $_POST['branch_name'] ?? null,
            'is_active'       => (int) ($_POST['is_active'] ?? 1),
            'notes'           => $_POST['notes'] ?? null,
        ]);

        $session = App::getInstance()->session();
        $session->flash('_alerts', [['type' => 'success', 'message' => 'تم تحديث الحساب البنكي بنجاح']]);
        return $this->redirect('/accounting/bank-accounts');
    }
}
