<?php

declare(strict_types=1);

namespace Maestro\Core\Http\Controllers\Superadmin;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Validation\Rule;
use Maestro\Core\Http\Controllers\Controller;
use Maestro\Core\Models\MaestroAppSetting;
use Maestro\Core\Support\MaestroAppSettingsPresenter;

class MaestroAppSettingsController extends Controller
{
    /**
     * @var list<string>
     */
    private const BRANDING_SLOTS = ['sidebar', 'header', 'compact', 'favicon', 'loginHero'];

    /**
     * @var array<string, string>
     */
    private const COLUMN_BY_SLOT = [
        'sidebar' => 'logo_sidebar_path',
        'header' => 'logo_header_path',
        'compact' => 'logo_compact_path',
        'favicon' => 'favicon_path',
        'loginHero' => 'login_hero_path',
    ];

    public function update(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'theme' => ['required', 'array'],
        ]);

        $row = MaestroAppSetting::instance();
        $incoming = self::normalizeThemePayload($validated['theme']);
        $row->theme = array_replace($row->theme ?? [], $incoming);
        $row->save();

        return response()->json(MaestroAppSettingsPresenter::toArray($row));
    }

    /**
     * @param  array<string, mixed>  $theme
     * @return array<string, mixed>
     */
    private static function normalizeThemePayload(array $theme): array
    {
        $out = [];

        foreach (['preset', 'primary', 'menuMode', 'menuTheme', 'cardStyle'] as $key) {
            if (! array_key_exists($key, $theme)) {
                continue;
            }
            $out[$key] = (string) $theme[$key];
        }

        if (array_key_exists('surface', $theme)) {
            $surface = $theme['surface'];
            $out['surface'] = ($surface === null || $surface === '') ? null : (string) $surface;
        }

        if (array_key_exists('darkTheme', $theme)) {
            $dark = $theme['darkTheme'];
            $parsed = filter_var($dark, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
            $out['darkTheme'] = $parsed ?? (bool) $dark;
        }

        return $out;
    }

    public function uploadBranding(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'slot' => ['required', 'string', Rule::in(self::BRANDING_SLOTS)],
            'file' => ['required', 'file', 'max:4096', 'mimes:png,jpg,jpeg,webp,gif,svg,ico'],
        ]);

        $column = self::COLUMN_BY_SLOT[$validated['slot']];
        $row = MaestroAppSetting::instance();

        $disk = Storage::disk('public');
        $path = $request->file('file')->store('branding', 'public');

        if ($row->{$column}) {
            $disk->delete($row->{$column});
        }

        $row->{$column} = $path;
        $row->save();

        return response()->json(MaestroAppSettingsPresenter::toArray($row));
    }

    public function clearBranding(string $slot): JsonResponse
    {
        abort_unless(in_array($slot, self::BRANDING_SLOTS, true), 404);

        $column = self::COLUMN_BY_SLOT[$slot];
        $row = MaestroAppSetting::instance();

        if ($row->{$column}) {
            Storage::disk('public')->delete($row->{$column});
            $row->{$column} = null;
            $row->save();
        }

        return response()->json(MaestroAppSettingsPresenter::toArray($row));
    }
}
