<?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\NegotiableInstrument;

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

        $direction = $request->get('direction', 'receivable');
        $status = $request->get('status', '');

        $qb = NegotiableInstrument::query()
            ->where('direction', '=', $direction);

        if ($status) {
            $qb->where('status', '=', $status);
        }

        $instruments = $qb->orderBy('due_date', 'ASC')->get();

        $db = App::getInstance()->db();
        $bankAccounts = $db->select("SELECT id, account_name_ar FROM bank_accounts WHERE is_active = 1 ORDER BY account_name_ar");

        return $this->view('Accounting/Views/instruments/index', [
            'instruments'  => $instruments,
            'direction'    => $direction,
            'status'       => $status,
            'bankAccounts' => $bankAccounts,
        ]);
    }

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

        $data = $this->validate($request->all(), [
            'instrument_type'   => 'required',
            'direction'         => 'required',
            'instrument_number' => 'required',
            'amount'            => 'required',
            'issue_date'        => 'required',
            'due_date'          => 'required',
        ]);

        $session = App::getInstance()->session();

        NegotiableInstrument::create([
            'instrument_type'   => $data['instrument_type'],
            'direction'         => $data['direction'],
            'instrument_number' => $data['instrument_number'],
            'amount'            => (float)$data['amount'],
            'currency'          => $request->post('currency', 'EGP'),
            'issue_date'        => $data['issue_date'],
            'due_date'          => $data['due_date'],
            'drawer_name'       => $request->post('drawer_name'),
            'drawer_bank'       => $request->post('drawer_bank'),
            'beneficiary_name'  => $request->post('beneficiary_name'),
            'member_id'         => $request->post('member_id') ? (int)$request->post('member_id') : null,
            'vendor_id'         => $request->post('vendor_id') ? (int)$request->post('vendor_id') : null,
            'bank_account_id'   => $request->post('bank_account_id') ? (int)$request->post('bank_account_id') : null,
            'notes'             => $request->post('notes'),
            'status'            => 'in_hand',
            'current_location'  => 'safe',
            'created_by'        => (int)($session->get('employee_id') ?? 0) ?: null,
        ]);

        return $this->redirect('/accounting/instruments?direction=' . $data['direction'])
            ->withSuccess('تم تسجيل الورقة التجارية بنجاح');
    }

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

        $instrument = NegotiableInstrument::findOrFail((int)$id);

        return $this->view('Accounting/Views/instruments/show', [
            'instrument' => $instrument->toArray(),
        ]);
    }

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

        $instrument = NegotiableInstrument::findOrFail((int)$id);
        $newStatus = $request->post('new_status');

        if (!$instrument->canTransitionTo($newStatus)) {
            return $this->redirect('/accounting/instruments/' . $id)
                ->withError('لا يمكن تغيير الحالة إلى: ' . (NegotiableInstrument::$statusLabels[$newStatus] ?? $newStatus));
        }

        $extra = [];
        if ($request->post('bank_account_id')) {
            $extra['bank_account_id'] = (int)$request->post('bank_account_id');
        }
        if ($request->post('endorsee_name')) {
            $extra['endorsee_name'] = $request->post('endorsee_name');
        }

        $instrument->transitionTo($newStatus, $extra ?: null);

        return $this->redirect('/accounting/instruments/' . $id)
            ->withSuccess('تم تغيير الحالة إلى: ' . (NegotiableInstrument::$statusLabels[$newStatus] ?? $newStatus));
    }

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

        $days = (int)($request->get('days') ?? 7);
        $instruments = NegotiableInstrument::getDueWithin($days);

        return $this->view('Accounting/Views/instruments/due_soon', [
            'instruments' => $instruments,
            'days'        => $days,
        ]);
    }
}
