<?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 ReceiptConfigController
{
    public function __construct(
        private readonly Template $template,
        private readonly Translator $translator,
        private readonly AuthService $auth,
        private readonly ReceiptConfigRepository $repository
    ) {
    }

    public function hub(Request $request): Response
    {
        $html = $this->template->render('settings/accounting', [
            'title' => $this->translator->get('settings.accounting.title'),
            'activeMenu' => 'settings',
            'activeSettings' => 'accounting',
            'user' => $this->auth->user(),
            'csrfToken' => Csrf::token(),
            'successMessage' => (string) Flash::get('settings.accounting.success', ''),
            'errorMessage' => (string) Flash::get('settings.accounting.error', ''),
        ], 'layouts/app');

        return Response::html($html);
    }

    public function list(Request $request): Response
    {
        $configs = $this->repository->listAll();

        $html = $this->template->render('settings/accounting-receipts', [
            'title' => 'Konfiguracje paragonow',
            'activeMenu' => 'settings',
            'activeSettings' => 'accounting',
            'user' => $this->auth->user(),
            'csrfToken' => Csrf::token(),
            'configs' => $configs,
            'successMessage' => (string) Flash::get('settings.accounting.success', ''),
            'errorMessage' => (string) Flash::get('settings.accounting.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('settings.accounting.error', 'Nie znaleziono konfiguracji paragonu ID ' . $id . '.');
            return Response::redirect('/settings/accounting/receipts');
        }

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

        return Response::html($html);
    }

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

        if (!Csrf::validate((string) $request->input('_token', ''))) {
            Flash::set('settings.accounting.error', 'Nieprawidlowy token CSRF');
            return Response::redirect($redirectFail);
        }

        $name = trim((string) $request->input('name', ''));
        $numberFormat = trim((string) $request->input('number_format', ''));

        if ($name === '') {
            Flash::set('settings.accounting.error', 'Nazwa konfiguracji jest wymagana');
            return Response::redirect($redirectFail);
        }

        if ($numberFormat === '' || strpos($numberFormat, '%N') === false) {
            Flash::set('settings.accounting.error', 'Format numeracji jest wymagany i musi zawierac %N');
            return Response::redirect($redirectFail);
        }

        try {
            $this->repository->save([
                'id' => $id > 0 ? $id : '',
                'name' => $name,
                'is_active' => $request->input('is_active', null),
                'number_format' => $numberFormat,
                'numbering_type' => $request->input('numbering_type', 'monthly'),
                'is_named' => $request->input('is_named', null),
                'sale_date_source' => $request->input('sale_date_source', 'issue_date'),
                'order_reference' => $request->input('order_reference', 'none'),
            ]);

            Flash::set('settings.accounting.success', $this->translator->get('settings.accounting.flash.saved'));
            return Response::redirect($redirectOk);
        } catch (Throwable) {
            Flash::set('settings.accounting.error', $this->translator->get('settings.accounting.flash.save_failed'));
            return Response::redirect($redirectFail);
        }
    }

    public function toggleStatus(Request $request): Response
    {
        $redirect = '/settings/accounting/receipts';
        if (!Csrf::validate((string) $request->input('_token', ''))) {
            Flash::set('settings.accounting.error', 'Nieprawidlowy token CSRF');
            return Response::redirect($redirect);
        }

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

        try {
            $this->repository->toggleStatus($id);
            Flash::set('settings.accounting.success', $this->translator->get('settings.accounting.flash.toggled'));
        } catch (Throwable) {
            Flash::set('settings.accounting.error', 'Blad zmiany statusu');
        }

        return Response::redirect($redirect);
    }

    public function delete(Request $request): Response
    {
        $redirect = '/settings/accounting/receipts';
        if (!Csrf::validate((string) $request->input('_token', ''))) {
            Flash::set('settings.accounting.error', 'Nieprawidlowy token CSRF');
            return Response::redirect($redirect);
        }

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

        try {
            $this->repository->delete($id);
            Flash::set('settings.accounting.success', $this->translator->get('settings.accounting.flash.deleted'));
        } catch (Throwable) {
            Flash::set('settings.accounting.error', $this->translator->get('settings.accounting.flash.delete_failed'));
        }

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