<?php
declare(strict_types=1);

namespace App\Modules\Accounting\Controllers;

use App\Core\Controller;
use App\Core\Request;
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(Request $request): Response
    {
        $this->authorize('accounting.bank_account.manage');

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

        $isDefault = (int) ($request->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' => $request->post('account_name_en', ''),
            'bank_name_ar'    => $data['bank_name_ar'],
            'bank_name_en'    => $request->post('bank_name_en'),
            'account_number'  => $data['account_number'],
            'iban'            => $request->post('iban'),
            'swift_code'      => $request->post('swift_code'),
            'branch_name'     => $request->post('branch_name'),
            'currency'        => $request->post('currency', 'EGP'),
            'gl_account_id'   => $request->post('gl_account_id') ? (int) $request->post('gl_account_id') : null,
            'opening_balance' => $request->post('opening_balance', '0.00'),
            'current_balance' => $request->post('opening_balance', '0.00'),
            'is_default'      => $isDefault,
            'is_active'       => 1,
            'notes'           => $request->post('notes'),
        ]);

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

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

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

        $account = BankAccount::findOrFail((int) $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(Request $request, string $id): Response
    {
        $this->authorize('accounting.bank_account.manage');

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

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

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

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