<?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\Account;
use App\Modules\Accounting\Models\CostCenter;

class ChartOfAccountsController extends Controller
{
    public function index(Request $request): Response
    {
        $this->authorize('accounting.coa.view');

        $search = trim($request->get('search', ''));
        $typeFilter = $request->get('type', '');

        $tree = Account::getTree();

        return $this->view('Accounting/Views/chart_of_accounts/index', [
            'tree'    => $tree,
            'search'  => $search,
            'type'    => $typeFilter,
        ]);
    }

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

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

        $costCenters = CostCenter::getActive();

        return $this->view('Accounting/Views/chart_of_accounts/create', [
            'parents'      => $parentAccounts,
            'cost_centers' => $costCenters,
        ]);
    }

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

        $data = $this->validate($request->all(), [
            'account_code'   => 'required',
            'name_ar'        => 'required',
            'name_en'        => 'required',
            'account_type'   => 'required|in:asset,liability,equity,revenue,expense',
            'account_nature' => 'required|in:debit,credit',
        ]);

        // Check unique code
        if (Account::findByCode($data['account_code'])) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', [['type' => 'error', 'message' => 'كود الحساب مستخدم بالفعل']]);
            return $this->redirect('/accounting/chart-of-accounts/create');
        }

        $parentId = $request->post('parent_id') ? (int) $request->post('parent_id') : null;
        $level = 1;
        if ($parentId) {
            $parent = Account::find($parentId);
            if ($parent) {
                $level = (int) $parent->level + 1;
            }
        }

        Account::create([
            'account_code'    => $data['account_code'],
            'name_ar'         => $data['name_ar'],
            'name_en'         => $data['name_en'],
            'account_type'    => $data['account_type'],
            'account_nature'  => $data['account_nature'],
            'parent_id'       => $parentId,
            'level'           => $level,
            'is_header'       => (int) ($request->post('is_header', 0)),
            'is_active'       => 1,
            'description_ar'  => $request->post('description_ar'),
            'description_en'  => $request->post('description_en'),
            'opening_balance' => $request->post('opening_balance', '0.00'),
            'cost_center_id'  => $request->post('cost_center_id') ? (int) $request->post('cost_center_id') : null,
        ]);

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

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

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

        $parentAccounts = Account::query()
            ->where('is_archived', '=', 0)
            ->where('is_header', '=', 1)
            ->where('id', '!=', (int) $id)
            ->orderBy('account_code', 'ASC')
            ->get();

        $costCenters = CostCenter::getActive();

        return $this->view('Accounting/Views/chart_of_accounts/edit', [
            'account'      => $account->toArray(),
            'parents'      => $parentAccounts,
            'cost_centers' => $costCenters,
        ]);
    }

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

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

        $data = $this->validate($request->all(), [
            'name_ar'        => 'required',
            'name_en'        => 'required',
            'account_type'   => 'required|in:asset,liability,equity,revenue,expense',
            'account_nature' => 'required|in:debit,credit',
        ]);

        // Cannot change code of system accounts
        if ((int) $account->is_system === 1 && ($request->post('account_code', '') !== $account->account_code)) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', [['type' => 'error', 'message' => 'لا يمكن تعديل كود حساب نظامي']]);
            return $this->redirect('/accounting/chart-of-accounts/' . (int) $id . '/edit');
        }

        $account->update([
            'name_ar'         => $data['name_ar'],
            'name_en'         => $data['name_en'],
            'account_type'    => $data['account_type'],
            'account_nature'  => $data['account_nature'],
            'is_header'       => (int) ($request->post('is_header', 0)),
            'is_active'       => (int) ($request->post('is_active', 1)),
            'description_ar'  => $request->post('description_ar'),
            'description_en'  => $request->post('description_en'),
            'cost_center_id'  => $request->post('cost_center_id') ? (int) $request->post('cost_center_id') : null,
        ]);

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

    public function search(Request $request): Response
    {
        $this->authorize('accounting.coa.view');

        $term = $request->get('q', '');
        $results = Account::search($term);

        return $this->json($results);
    }
}
