<?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(): Response
    {
        $this->authorize('accounting.coa.view');

        $search = trim($_GET['search'] ?? '');
        $typeFilter = $_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(): Response
    {
        $this->authorize('accounting.coa.manage');

        $data = $this->validate($_POST, [
            '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 = !empty($_POST['parent_id']) ? (int) $_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) ($_POST['is_header'] ?? 0),
            'is_active'       => 1,
            'description_ar'  => $_POST['description_ar'] ?? null,
            'description_en'  => $_POST['description_en'] ?? null,
            'opening_balance' => $_POST['opening_balance'] ?? '0.00',
            'cost_center_id'  => !empty($_POST['cost_center_id']) ? (int) $_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($_POST, [
            '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 && ($_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) ($_POST['is_header'] ?? 0),
            'is_active'       => (int) ($_POST['is_active'] ?? 1),
            'description_ar'  => $_POST['description_ar'] ?? null,
            'description_en'  => $_POST['description_en'] ?? null,
            'cost_center_id'  => !empty($_POST['cost_center_id']) ? (int) $_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(): Response
    {
        $this->authorize('accounting.coa.view');

        $term = $_GET['q'] ?? '';
        $results = Account::search($term);

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