<?php

declare(strict_types=1);

namespace App\Http\Requests\NovaCards;

use App\Models\NovaCard;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class SaveNovaCardDraftRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user() !== null;
    }

    public function rules(): array
    {
        $validation = (array) config('nova_cards.validation', []);

        return [
            'title' => ['sometimes', 'string', 'min:2', 'max:' . (int) ($validation['title_max'] ?? 120)],
            'quote_text' => ['sometimes', 'string', 'min:' . (int) ($validation['quote_min'] ?? 3), 'max:' . (int) ($validation['quote_max'] ?? 420)],
            'quote_author' => ['sometimes', 'nullable', 'string', 'max:160'],
            'quote_source' => ['sometimes', 'nullable', 'string', 'max:180'],
            'description' => ['sometimes', 'nullable', 'string', 'max:' . (int) ($validation['description_max'] ?? 500)],
            'format' => ['sometimes', Rule::in(array_keys((array) config('nova_cards.formats', [])))],
            'template_id' => ['sometimes', 'nullable', 'integer', 'exists:nova_card_templates,id'],
            'category_id' => ['sometimes', 'nullable', 'integer', 'exists:nova_card_categories,id'],
            'background_type' => ['sometimes', Rule::in(['gradient', 'upload', 'template', 'solid'])],
            'background_image_id' => ['sometimes', 'nullable', 'integer', 'exists:nova_card_backgrounds,id'],
            'visibility' => ['sometimes', Rule::in([NovaCard::VISIBILITY_PUBLIC, NovaCard::VISIBILITY_UNLISTED, NovaCard::VISIBILITY_PRIVATE])],
            'allow_download' => ['sometimes', 'boolean'],
            'allow_remix' => ['sometimes', 'boolean'],
            'editor_mode_last_used' => ['sometimes', Rule::in(['quick', 'full'])],
            'publish_mode' => ['sometimes', Rule::in(['now', 'schedule'])],
            'scheduled_for' => ['sometimes', 'nullable', 'date'],
            'scheduling_timezone' => ['sometimes', 'nullable', 'string', 'max:64'],
            'tags' => ['sometimes', 'array', 'max:' . (int) ($validation['max_tags'] ?? 8)],
            'tags.*' => ['string', 'min:2', 'max:32'],
            'project_json' => ['sometimes', 'array'],
            'project_json.schema_version' => ['sometimes', 'integer', 'min:1', 'max:9'],
            'project_json.text_blocks' => ['sometimes', 'array', 'max:' . (int) ($validation['max_text_blocks'] ?? 8)],
            'project_json.text_blocks.*.key' => ['sometimes', 'string', 'max:40'],
            'project_json.text_blocks.*.type' => ['sometimes', Rule::in(['title', 'quote', 'author', 'source', 'body', 'caption'])],
            'project_json.text_blocks.*.text' => ['sometimes', 'nullable', 'string', 'max:' . (int) ($validation['quote_max'] ?? 420)],
            'project_json.text_blocks.*.enabled' => ['sometimes', 'boolean'],
            'project_json.text_blocks.*.pos_x' => ['sometimes', 'nullable', 'numeric', 'min:0', 'max:100'],
            'project_json.text_blocks.*.pos_y' => ['sometimes', 'nullable', 'numeric', 'min:0', 'max:100'],
            'project_json.text_blocks.*.pos_width' => ['sometimes', 'nullable', 'numeric', 'min:1', 'max:100'],
            'project_json.assets.pack_ids' => ['sometimes', 'array'],
            'project_json.assets.pack_ids.*' => ['integer'],
            'project_json.assets.template_pack_ids' => ['sometimes', 'array'],
            'project_json.assets.template_pack_ids.*' => ['integer'],
            'project_json.assets.items' => ['sometimes', 'array', 'max:' . (int) ($validation['max_asset_items'] ?? 12)],
            'project_json.assets.items.*.asset_key' => ['sometimes', 'string', 'max:80'],
            'project_json.assets.items.*.label' => ['sometimes', 'string', 'max:120'],
            'project_json.assets.items.*.glyph' => ['sometimes', 'string', 'max:4'],
            'project_json.layout.alignment' => ['sometimes', Rule::in((array) ($validation['allowed_alignments'] ?? ['left', 'center', 'right']))],
            'project_json.layout.layout' => ['sometimes', Rule::in((array) ($validation['allowed_layouts'] ?? []))],
            'project_json.layout.position' => ['sometimes', Rule::in((array) ($validation['allowed_positions'] ?? []))],
            'project_json.layout.padding' => ['sometimes', Rule::in((array) ($validation['allowed_padding_presets'] ?? []))],
            'project_json.layout.max_width' => ['sometimes', Rule::in((array) ($validation['allowed_max_widths'] ?? []))],
            'project_json.typography.font_preset' => ['sometimes', Rule::in(array_keys((array) config('nova_cards.font_presets', [])))],
            'project_json.typography.quote_size' => ['sometimes', 'integer', 'min:10', 'max:160'],
            'project_json.typography.quote_width' => ['sometimes', 'nullable', 'integer', 'min:30', 'max:100'],
            'project_json.typography.text_opacity' => ['sometimes', 'nullable', 'integer', 'min:10', 'max:100'],
            'project_json.decorations' => ['sometimes', 'array'],
            'project_json.decorations.*.pos_x' => ['sometimes', 'nullable', 'numeric', 'min:0', 'max:100'],
            'project_json.decorations.*.pos_y' => ['sometimes', 'nullable', 'numeric', 'min:0', 'max:100'],
            'project_json.decorations.*.opacity' => ['sometimes', 'nullable', 'integer', 'min:10', 'max:100'],
            'project_json.typography.author_size' => ['sometimes', 'integer', 'min:12', 'max:72'],
            'project_json.typography.letter_spacing' => ['sometimes', 'integer', 'min:-2', 'max:12'],
            'project_json.typography.line_height' => ['sometimes', 'numeric', 'min:0.9', 'max:1.8'],
            'project_json.typography.shadow_preset' => ['sometimes', Rule::in(array_column((array) config('nova_cards.shadow_presets', []), 'key'))],
            'project_json.typography.text_color' => ['sometimes', 'regex:/^#(?:[0-9a-fA-F]{3}){1,2}$/'],
            'project_json.typography.accent_color' => ['sometimes', 'regex:/^#(?:[0-9a-fA-F]{3}){1,2}$/'],
            'project_json.background.type' => ['sometimes', Rule::in(['gradient', 'upload', 'template', 'solid'])],
            'project_json.background.gradient_preset' => ['sometimes', Rule::in(array_keys((array) config('nova_cards.gradient_presets', [])))],
            'project_json.background.gradient_colors' => ['sometimes', 'array', 'min:2', 'max:3'],
            'project_json.background.gradient_colors.*' => ['regex:/^#(?:[0-9a-fA-F]{3}){1,2}$/'],
            'project_json.background.solid_color' => ['sometimes', 'regex:/^#(?:[0-9a-fA-F]{3}){1,2}$/'],
            'project_json.background.overlay_style' => ['sometimes', Rule::in((array) ($validation['allowed_overlay_styles'] ?? []))],
            'project_json.background.focal_position' => ['sometimes', Rule::in(array_column((array) config('nova_cards.focal_positions', []), 'key'))],
            'project_json.background.blur_level' => ['sometimes', Rule::in((array) ($validation['allowed_blur_levels'] ?? []))],
            'project_json.background.opacity' => ['sometimes', Rule::in((array) ($validation['allowed_opacity_levels'] ?? []))],
            'project_json.source_context.editor_mode' => ['sometimes', Rule::in(['quick', 'full'])],
            'project_json.decorations' => ['sometimes', 'array', 'max:' . (int) ($validation['max_decorations'] ?? 6)],
            'project_json.decorations.*.key' => ['sometimes', 'string', 'max:40'],
            'project_json.decorations.*.glyph' => ['sometimes', 'string', 'max:4'],
            'project_json.decorations.*.placement' => ['sometimes', 'string', 'max:24'],
            'project_json.decorations.*.x' => ['sometimes', 'numeric', 'min:0', 'max:1920'],
            'project_json.decorations.*.y' => ['sometimes', 'numeric', 'min:0', 'max:1920'],
            'project_json.decorations.*.size' => ['sometimes', 'integer', 'min:2', 'max:120'],
        ];
    }
}
