<?php
declare(strict_types=1);

namespace App\Modules\Settings;

use App\Core\Http\Request;
use App\Core\Http\Response;
use App\Core\I18n\Translator;
use App\Core\Security\Csrf;
use App\Core\Support\Flash;
use App\Core\View\Template;
use App\Modules\Auth\AuthService;
use Throwable;

final class InvoiceConfigController
{
    public function __construct(
        private readonly Template $template,
        private readonly Translator $translator,
        private readonly AuthService $auth,
        private readonly InvoiceConfigRepository $repository,
        private readonly FakturowniaIntegrationRepository $fakturownia
    ) {
    }

    public function index(Request $request): Response
    {
        $configs = $this->repository->listAll();
        $settings = $this->fakturownia->getSettings();

        $html = $this->template->render('settings/accounting-invoices', [
            'title' => 'Konfiguracje faktur',
            'activeMenu' => 'settings',
            'activeSettings' => 'accounting',
            'user' => $this->auth->user(),
            'csrfToken' => Csrf::token(),
            'configs' => $configs,
            'fakturowniaSettings' => $settings,
            'successMessage' => (string) Flash::get('accounting.invoices.save', ''),
            'errorMessage' => (string) Flash::get('accounting.invoices.error', ''),
        ], 'layouts/app');

        return Response::html($html);
    }

    public function edit(Request $request): Response
    {
        $id = (int) $request->input('id', 0);
        $config = $id > 0 ? $this->repository->findById($id) : null;

        if ($id > 0 && $config === null) {
            Flash::set('accounting.invoices.error', 'Nie znaleziono konfiguracji faktury ID ' . $id . '.');
            return Response::redirect('/settings/accounting/invoices');
        }

        $settings = $this->fakturownia->getSettings();

        $html = $this->template->render('settings/accounting-invoice-edit', [
            'title' => $config === null ? 'Nowa konfiguracja faktury' : 'Edycja konfiguracji faktury',
            'activeMenu' => 'settings',
            'activeSettings' => 'accounting',
            'user' => $this->auth->user(),
            'csrfToken' => Csrf::token(),
            'config' => $config,
            'fakturowniaSettings' => $settings,
            'successMessage' => (string) Flash::get('accounting.invoices.save', ''),
            'errorMessage' => (string) Flash::get('accounting.invoices.error', ''),
        ], 'layouts/app');

        return Response::html($html);
    }

    public function save(Request $request): Response
    {
        $id = (int) $request->input('id', 0);
        $redirectFail = $id > 0
            ? '/settings/accounting/invoices/edit?id=' . $id
            : '/settings/accounting/invoices/new';

        if (!Csrf::validate((string) $request->input('_token', ''))) {
            Flash::set('accounting.invoices.error', $this->translator->get('auth.errors.csrf_expired'));
            return Response::redirect($redirectFail);
        }

        try {
            $this->repository->save([
                'id' => $id > 0 ? $id : '',
                'name' => (string) $request->input('name', ''),
                'number_format' => (string) $request->input('number_format', ''),
                'numbering_type' => (string) $request->input('numbering_type', 'monthly'),
                'sale_date_source' => (string) $request->input('sale_date_source', 'issue_date'),
                'order_reference' => (string) $request->input('order_reference', 'none'),
                'payment_to_days' => (int) $request->input('payment_to_days', 7),
                'default_kind' => (string) $request->input('default_kind', 'vat'),
                'is_delegated' => $request->input('is_delegated', ''),
                'integration_id' => $this->fakturownia->getIntegrationId(),
                'is_active' => $request->input('is_active', ''),
            ]);

            Flash::set('accounting.invoices.save', 'Zapisano konfiguracje faktury.');
            return Response::redirect('/settings/accounting/invoices');
        } catch (Throwable $exception) {
            Flash::set('accounting.invoices.error', $exception->getMessage());
            return Response::redirect($redirectFail);
        }
    }

    public function toggleStatus(Request $request): Response
    {
        $redirect = '/settings/accounting/invoices';
        if (!Csrf::validate((string) $request->input('_token', ''))) {
            Flash::set('accounting.invoices.error', $this->translator->get('auth.errors.csrf_expired'));
            return Response::redirect($redirect);
        }

        $id = (int) $request->input('id', 0);
        if ($id <= 0) {
            Flash::set('accounting.invoices.error', 'Brak identyfikatora konfiguracji.');
            return Response::redirect($redirect);
        }

        try {
            $this->repository->toggleStatus($id);
            Flash::set('accounting.invoices.save', 'Zmieniono status konfiguracji.');
        } catch (Throwable $exception) {
            Flash::set('accounting.invoices.error', $exception->getMessage());
        }

        return Response::redirect($redirect);
    }

    public function delete(Request $request): Response
    {
        $redirect = '/settings/accounting/invoices';
        if (!Csrf::validate((string) $request->input('_token', ''))) {
            Flash::set('accounting.invoices.error', $this->translator->get('auth.errors.csrf_expired'));
            return Response::redirect($redirect);
        }

        $id = (int) $request->input('id', 0);
        if ($id <= 0) {
            Flash::set('accounting.invoices.error', 'Brak identyfikatora konfiguracji.');
            return Response::redirect($redirect);
        }

        try {
            $this->repository->delete($id);
            Flash::set('accounting.invoices.save', 'Usunieto konfiguracje faktury.');
        } catch (Throwable $exception) {
            Flash::set('accounting.invoices.error', $exception->getMessage());
        }

        return Response::redirect($redirect);
    }
}
