<?php
namespace App\Controllers\Accounting;

use App\Controllers\BaseController;
use Config\Database;

class JournalVouchers extends BaseController
{
    public function index()
    {
        $db = Database::connect();
        $vouchers = [];
        try {
            $vouchers = $db->table('journal_vouchers')->orderBy('id','desc')->get()->getResultArray();
        } catch (\Throwable $e) { $vouchers = []; }
        return view('accounting/journal_vouchers/index', [
            'title' => lang('App.journal_vouchers'),
            'vouchers' => $vouchers,
        ]);
    }

    public function create()
    {
        $db = Database::connect();
        $accounts = [];
        try {
            $accounts = $db->table('chart_of_accounts')->where('is_postable', 1)->orderBy('code','asc')->get()->getResultArray();
        } catch (\Throwable $e) { $accounts = []; }
        $isArabic = (service('language')->getLocale() === 'ar');
        $accountList = [];
        foreach ($accounts as $a) {
            $name = $isArabic ? ($a['name_ar'] ?? $a['name_en']) : $a['name_en'];
            $accountList[] = [
                'code' => $a['code'],
                'display' => $name ?? '',
            ];
        }
        return view('accounting/journal_vouchers/form', [
            'title' => lang('App.journal_vouchers'),
            'accounts' => $accountList,
        ]);
    }

    public function store()
    {
        $req = $this->request;
        $db = Database::connect();
        $date = $req->getPost('date') ?: date('Y-m-d');
        $description = trim((string) $req->getPost('description'));
        $lines = $req->getPost('lines') ?? [];

        if (!is_array($lines) || count($lines) < 2) {
            return redirect()->back()->with('error', 'At least two lines are required.');
        }

        $totalDebit = 0.0; $totalCredit = 0.0; $clean = [];
        foreach ($lines as $ln) {
            $code = trim((string) ($ln['account_code'] ?? ''));
            $debit = (float) ($ln['debit'] ?? 0);
            $credit = (float) ($ln['credit'] ?? 0);
            $narr = trim((string) ($ln['narration'] ?? ''));
            if ($code === '' || ($debit <= 0 && $credit <= 0)) { continue; }
            $totalDebit += $debit; $totalCredit += $credit;
            $clean[] = ['account_code'=>$code,'debit'=>$debit,'credit'=>$credit,'narration'=>$narr];
        }
        if (abs($totalDebit - $totalCredit) > 0.0001) {
            return redirect()->back()->with('error', 'Debits must equal credits.');
        }
        if (count($clean) < 2) {
            return redirect()->back()->with('error', 'Please provide valid lines with amounts.');
        }

        try {
            $db->transBegin();
            $voucherNo = 'JV-' . date('Ymd-His');
            $db->table('journal_vouchers')->insert([
                'voucher_no' => $voucherNo,
                'date' => $date,
                'description' => $description,
                'created_at' => date('Y-m-d H:i:s'),
            ]);
            $voucherId = (int) $db->insertID();
            $lineNo = 0;
            foreach ($clean as $ln) {
                $lineNo++;
                $db->table('journal_lines')->insert([
                    'voucher_id' => $voucherId,
                    'account_code' => $ln['account_code'],
                    'narration' => $ln['narration'],
                    'debit' => $ln['debit'],
                    'credit' => $ln['credit'],
                ]);
                // Post to general ledger
                $db->table('general_ledger')->insert([
                    'entry_date' => $date,
                    'source_type' => 'JV',
                    'source_id' => $voucherId,
                    'line_no' => $lineNo,
                    'voucher_no' => $voucherNo,
                    'account_code' => $ln['account_code'],
                    'description' => $ln['narration'],
                    'debit' => $ln['debit'],
                    'credit' => $ln['credit'],
                    'created_at' => date('Y-m-d H:i:s'),
                ]);
            }
            $db->transComplete();
            return redirect()->to('/accounting/journal-vouchers')->with('success', 'Journal Voucher saved: ' . $voucherNo);
        } catch (\Throwable $e) {
            $db->transRollback();
            return redirect()->back()->with('error', 'Failed to save JV: ' . $e->getMessage());
        }
    }
}

