<?php

declare(strict_types=1);

namespace App\Modules\Settings;

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

final class ProjectMappingController
{
    private const SCRIPTS_DIR = 'tools/generowanie';

    public function __construct(
        private readonly Template $template,
        private readonly Translator $translator,
        private readonly AuthService $auth,
        private readonly ProjectMappingRepository $repository,
        private readonly string $basePath
    ) {
    }

    public function index(Request $request): Response
    {
        $mappings = $this->repository->getAll();
        $scripts = $this->scanScripts();

        $html = $this->template->render('settings/project-mappings', [
            'title' => $this->translator->get('settings.project_mapping.title'),
            'activeMenu' => 'settings',
            'activeSettings' => 'project-mappings',
            'user' => $this->auth->user(),
            'csrfToken' => Csrf::token(),
            'mappings' => $mappings,
            'scripts' => $scripts,
            'errorMessage' => (string) Flash::get('settings_error', ''),
            'successMessage' => (string) Flash::get('settings_success', ''),
        ], 'layouts/app');

        return Response::html($html);
    }

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

        $pattern = trim((string) $request->input('product_name_pattern', ''));
        $scriptName = trim((string) $request->input('script_name', ''));
        $outputDir = trim((string) $request->input('output_dir', ''));
        $requiresPhoto = (string) $request->input('requires_photo', '') !== '';

        if ($pattern === '' || $scriptName === '') {
            Flash::set('settings_error', $this->translator->get('settings.project_mapping.flash.validation_error'));
            return Response::redirect('/settings/project-mappings');
        }

        $scriptPath = $this->basePath . '/' . self::SCRIPTS_DIR . '/' . $scriptName;
        if (!file_exists($scriptPath)) {
            Flash::set('settings_error', $this->translator->get('settings.project_mapping.flash.script_not_found'));
            return Response::redirect('/settings/project-mappings');
        }

        $this->repository->create([
            'product_name_pattern' => $pattern,
            'script_name' => $scriptName,
            'output_dir' => $outputDir !== '' ? $outputDir : null,
            'requires_photo' => $requiresPhoto ? 1 : 0,
        ]);

        Flash::set('settings_success', $this->translator->get('settings.project_mapping.flash.created'));
        return Response::redirect('/settings/project-mappings');
    }

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

        $id = (int) $request->input('id', '0');
        $pattern = trim((string) $request->input('product_name_pattern', ''));
        $scriptName = trim((string) $request->input('script_name', ''));
        $outputDir = trim((string) $request->input('output_dir', ''));
        $requiresPhoto = (string) $request->input('requires_photo', '') !== '';

        if ($id <= 0 || $pattern === '' || $scriptName === '') {
            Flash::set('settings_error', $this->translator->get('settings.project_mapping.flash.validation_error'));
            return Response::redirect('/settings/project-mappings');
        }

        $this->repository->update($id, [
            'product_name_pattern' => $pattern,
            'script_name' => $scriptName,
            'output_dir' => $outputDir !== '' ? $outputDir : null,
            'requires_photo' => $requiresPhoto ? 1 : 0,
        ]);

        Flash::set('settings_success', $this->translator->get('settings.project_mapping.flash.updated'));
        return Response::redirect('/settings/project-mappings');
    }

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

        $id = (int) $request->input('id', '0');
        if ($id > 0) {
            $this->repository->delete($id);
            Flash::set('settings_success', $this->translator->get('settings.project_mapping.flash.deleted'));
        }

        return Response::redirect('/settings/project-mappings');
    }

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

        $id = (int) $request->input('id', '0');
        if ($id > 0) {
            $this->repository->toggleActive($id);
            Flash::set('settings_success', $this->translator->get('settings.project_mapping.flash.toggled'));
        }

        return Response::redirect('/settings/project-mappings');
    }

    private function scanScripts(): array
    {
        $dir = $this->basePath . '/' . self::SCRIPTS_DIR;
        if (!is_dir($dir)) {
            return [];
        }

        $files = glob($dir . '/*.py');
        $scripts = [];
        foreach ($files as $file) {
            $scripts[] = basename($file);
        }
        sort($scripts);

        return $scripts;
    }
}
