<?php

namespace Workdo\Account\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;
use Workdo\Account\Models\JournalEntry;
use Workdo\Account\Models\JournalEntryItem;
use Workdo\Account\Models\ChartOfAccount;
use Workdo\Account\Services\JournalService;

class ManualJournalController extends Controller
{
    protected $journalService;

    public function __construct(JournalService $journalService)
    {
        $this->journalService = $journalService;
    }

    public function index(Request $request)
    {
        if(Auth::user()->can('manage-account')){
            $query = JournalEntry::with('items.account')
                ->where('created_by', creatorId())
                ->where('entry_type', 'manual')
                ->latest();

            if ($request->search) {
                $query->where('journal_number', 'like', '%' . $request->search . '%')
                      ->orWhere('description', 'like', '%' . $request->search . '%');
            }
            if ($request->date_from && $request->date_to) {
                $query->whereBetween('journal_date', [$request->date_from, $request->date_to]);
            }

            $journals = $query->paginate($request->per_page ?? 10)->withQueryString();

            return Inertia::render('Account/ManualJournals/Index', [
                'journals' => $journals,
                'filters' => $request->only(['search', 'date_from', 'date_to'])
            ]);
        }
        else{
            return back()->with('error', __('Permission denied'));
        }
    }

    public function create()
    {
        if(Auth::user()->can('manage-account')){
            $chartOfAccounts = ChartOfAccount::where('created_by', creatorId())
                ->where('is_active', true)
                ->select('id', 'account_code', 'account_name')
                ->orderBy('account_code')
                ->get();

            return Inertia::render('Account/ManualJournals/Create', [
                'chartOfAccounts' => $chartOfAccounts,
            ]);
        }
        else{
            return back()->with('error', __('Permission denied'));
        }
    }

    public function store(Request $request)
    {
        if(Auth::user()->can('manage-account')){
            $request->validate([
                'journal_date' => 'required|date',
                'description' => 'required|string',
                'items' => 'required|array|min:2',
                'items.*.account_id' => 'required|exists:chart_of_accounts,id',
                'items.*.debit' => 'nullable|numeric|min:0',
                'items.*.credit' => 'nullable|numeric|min:0',
            ]);

            $totalDebit = 0;
            $totalCredit = 0;

            foreach ($request->items as $item) {
                $totalDebit += isset($item['debit']) && $item['debit'] !== '' ? (float)$item['debit'] : 0;
                $totalCredit += isset($item['credit']) && $item['credit'] !== '' ? (float)$item['credit'] : 0;
            }

            if (abs($totalDebit - $totalCredit) > 0.01) {
                return back()->with('error', __('Total Debit must be equal to Total Credit.'));
            }

            if ($totalDebit <= 0) {
                return back()->with('error', __('Amount must be greater than zero.'));
            }

            // Generate Journal Number
            $lastJournal = JournalEntry::where('created_by', creatorId())->latest('id')->first();
            $nextId = $lastJournal ? $lastJournal->id + 1 : 1;
            $journalNumber = 'JOU-' . str_pad($nextId, 5, '0', STR_PAD_LEFT);

            $journalEntry = JournalEntry::create([
                'journal_number' => $journalNumber,
                'journal_date' => $request->journal_date,
                'entry_type' => 'manual',
                'reference_type' => 'manual',
                'reference_id' => 0,
                'description' => $request->description,
                'total_debit' => $totalDebit,
                'total_credit' => $totalCredit,
                'status' => 'posted',
                'creator_id' => Auth::id(),
                'created_by' => creatorId()
            ]);

            foreach ($request->items as $item) {
                $debit = isset($item['debit']) && $item['debit'] !== '' ? (float)$item['debit'] : 0;
                $credit = isset($item['credit']) && $item['credit'] !== '' ? (float)$item['credit'] : 0;

                if ($debit > 0 || $credit > 0) {
                    JournalEntryItem::create([
                        'journal_entry_id' => $journalEntry->id,
                        'account_id' => $item['account_id'],
                        'description' => $request->description,
                        'debit_amount' => $debit,
                        'credit_amount' => $credit,
                        'creator_id' => Auth::id(),
                        'created_by' => creatorId()
                    ]);
                }
            }

            $this->journalService->processManualJournal($journalEntry);

            return redirect()->route('account.manual-journals.index')->with('success', __('Manual Journal Entry posted successfully.'));
        }
        else{
            return back()->with('error', __('Permission denied'));
        }
    }

    public function show(JournalEntry $manual_journal)
    {
        if(Auth::user()->can('manage-account')){
            $manual_journal->load('items.account');
            
            return Inertia::render('Account/ManualJournals/Show', [
                'journal' => $manual_journal,
            ]);
        }
        else{
            return back()->with('error', __('Permission denied'));
        }
    }

    public function edit(JournalEntry $manual_journal)
    {
        if(Auth::user()->can('manage-account')){
            $chartOfAccounts = ChartOfAccount::where('created_by', creatorId())
                ->where('is_active', true)
                ->select('id', 'account_code', 'account_name')
                ->orderBy('account_code')
                ->get();

            $manual_journal->load('items');

            return Inertia::render('Account/ManualJournals/Edit', [
                'journal' => $manual_journal,
                'chartOfAccounts' => $chartOfAccounts,
            ]);
        }
        else{
            return back()->with('error', __('Permission denied'));
        }
    }

    public function update(Request $request, JournalEntry $manual_journal)
    {
        if(Auth::user()->can('manage-account')){
            $request->validate([
                'journal_date' => 'required|date',
                'description' => 'required|string',
                'items' => 'required|array|min:2',
                'items.*.account_id' => 'required|exists:chart_of_accounts,id',
                'items.*.debit' => 'nullable|numeric|min:0',
                'items.*.credit' => 'nullable|numeric|min:0',
            ]);

            $totalDebit = 0;
            $totalCredit = 0;
            $itemsData = [];

            foreach ($request->items as $item) {
                $debit = isset($item['debit']) && $item['debit'] !== '' ? (float)$item['debit'] : 0;
                $credit = isset($item['credit']) && $item['credit'] !== '' ? (float)$item['credit'] : 0;
                
                $totalDebit += $debit;
                $totalCredit += $credit;

                if ($debit > 0 || $credit > 0) {
                    $itemsData[] = [
                        'account_id' => $item['account_id'],
                        'debit_amount' => $debit,
                        'credit_amount' => $credit,
                        'creator_id' => Auth::id(),
                        'created_by' => creatorId()
                    ];
                }
            }

            if (abs($totalDebit - $totalCredit) > 0.01) {
                return back()->with('error', __('Total Debit must be equal to Total Credit.'));
            }

            if ($totalDebit <= 0) {
                return back()->with('error', __('Amount must be greater than zero.'));
            }

            $journalData = [
                'journal_date' => $request->journal_date,
                'description' => $request->description,
                'total_debit' => $totalDebit,
                'total_credit' => $totalCredit,
            ];

            $this->journalService->updateManualJournal($manual_journal, $journalData, $itemsData);

            return redirect()->route('account.manual-journals.index')->with('success', __('Manual Journal Entry updated successfully.'));
        }
        else{
            return back()->with('error', __('Permission denied'));
        }
    }

    public function destroy(JournalEntry $manual_journal)
    {
        if(Auth::user()->can('manage-account')){
            if ($manual_journal->created_by == creatorId()) {
                $this->journalService->deleteManualJournal($manual_journal);
                return back()->with('success', __('Manual Journal Entry deleted successfully.'));
            }
            return back()->with('error', __('Permission denied.'));
        }
        else{
            return back()->with('error', __('Permission denied'));
        }
    }
}
