<?php

namespace App\Http\Controllers\Admin;

use App\Core\Repositories\ChartOfAccountRepository;
use App\Core\Repositories\JournalEntryRepository;
use App\Core\Services\Accounting\JournalEntryService;
use App\Http\Controllers\Controller;
use App\Models\JournalEntry;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class JournalEntryController extends Controller
{
    public function __construct(
        private JournalEntryService $service,
        private JournalEntryRepository $repository,
        private ChartOfAccountRepository $accountRepository
    ) {}

    /**
     * Display a listing of journal entries
     */
    public function index(Request $request): View
    {
        $filters = [
            'status' => $request->get('status'),
            'date_from' => $request->get('date_from'),
            'date_to' => $request->get('date_to'),
            'search' => $request->get('search'),
        ];

        $entries = $this->repository->getPaginated(15, $filters);

        return view('admin.accounting.journal-entries.index', [
            'entries' => $entries,
            'filters' => $filters,
        ]);
    }

    /**
     * Show the form for creating a new journal entry
     */
    public function create(): View
    {
        $accounts = $this->accountRepository->getAll();

        return view('admin.accounting.journal-entries.create', [
            'accounts' => $accounts,
        ]);
    }

    /**
     * Store a newly created journal entry
     */
    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'entry_date' => 'required|date',
            'description' => 'nullable|string',
            'status' => 'nullable|in:draft,posted',
            'lines' => 'required|array|min:2',
            'lines.*.account_id' => 'required|exists:chart_of_accounts,id',
            'lines.*.type' => 'required|in:debit,credit',
            'lines.*.amount' => 'required|numeric|min:0.01',
            'lines.*.description' => 'nullable|string',
        ]);

        $entry = $this->service->create($validated);

        return redirect()
            ->route('admin.journal-entries.show', $entry)
            ->with('success', 'Journal entry created successfully.');
    }

    /**
     * Display the specified journal entry
     */
    public function show(JournalEntry $journalEntry): View
    {
        $journalEntry->load(['lines.account', 'creator', 'reverser']);

        return view('admin.accounting.journal-entries.show', [
            'entry' => $journalEntry,
        ]);
    }

    /**
     * Post a journal entry
     */
    public function post(JournalEntry $journalEntry): RedirectResponse
    {
        $this->service->post($journalEntry);

        return redirect()
            ->route('admin.journal-entries.show', $journalEntry)
            ->with('success', 'Journal entry posted successfully.');
    }

    /**
     * Reverse a journal entry
     */
    public function reverse(JournalEntry $journalEntry): RedirectResponse
    {
        $reversingEntry = $this->service->reverse($journalEntry);

        return redirect()
            ->route('admin.journal-entries.show', $reversingEntry)
            ->with('success', 'Journal entry reversed successfully.');
    }
}
