<?php

namespace App\Http\Requests;

use App\Enums\TipoPromocion;
use App\Traits\ConvertsBase64ToFiles;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class PromocionesRequest extends FormRequest
{
    use ConvertsBase64ToFiles;

    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
     */
    public function rules(): array
    {
        $operadores = $this->input('operadores');

        if ($operadores) {
            return [
                'titulo' => 'required|min:3|max:85',

                'descripcion' => 'required',
                'fecha_desde' => 'required|date',
                'fecha_hasta' => 'required|date',

                'imagen' =>   $this->imageRule(),
                'estado' => 'required',
                'orden' => 'nullable|numeric',
                'app' => ['nullable', Rule::enum(TipoPromocion::class)],
            ];
        }
        return [
            'titulo' => "required|min:3|max:85",
            'subtitulo' => 'nullable|string|min:3|max:85',
            'copete' => 'nullable|max:85',
            'dias' => 'required|array|min:1',

            'fecha_desde' => 'required|date',
            'fecha_hasta' => 'required|date',

            'estaciones' => 'nullable|array',
            'servicios' => 'nullable|array',
            'metodos_pagos' => 'nullable|array',

            'imagen' =>   $this->imageRule(),
            'descripcion' => 'nullable|string|max:5000',
            'popup' => 'nullable|boolean',
            'estado' => 'nullable|boolean',
            'orden' => 'nullable|numeric',
            'app' => ['nullable', Rule::enum(TipoPromocion::class)],
            'bank_id' => 'nullable|numeric|exists:banks,id',
            'servicio_id' => 'nullable|numeric',
            'terminos_file_id' => 'nullable|numeric',
            'estaciones_file_id' => 'nullable|numeric',
            'archivo_file_id' => 'nullable|numeric',
        ];
    }

    protected function prepareForValidation()
    {
        $input = $this->input();
        $input['servicios'] = isset($input['servicio_id']) && $input['servicio_id']
            ? [$input['servicio_id']]
            : ($input['servicios'] ?? []);
        $input['estado'] = $input['estado'] ?? 1;
        $input['popup'] = filter_var($input['popup'] ?? false, FILTER_VALIDATE_BOOLEAN);
        $input['app'] = $this->normalizeTipoPromocion($input['app'] ?? null);
        $input['copete'] = $input['copete'] ?? null;
        $input['descripcion'] = $input['descripcion'] ?? null;
        $input['bank_id'] = ($input['bank_id'] ?? null) !== ''
            ? ($input['bank_id'] ?? null)
            : null;
        $input['estaciones'] = $input['estaciones'] ?? [];
        $input['metodos_pagos'] = $input['metodos_pagos'] ?? [];
        $input['dias'] = $input['dias'] ?? [];

        if ($this->method() !== 'POST') {
            $isBase64 = isset($input['imagen']) && isImageBase64($input['imagen']);

            if (!$isBase64) {
                unset($input['imagen']);
                $this->replace($input ?? []);
                return;
            }
        }

        $this->convertBase64ToFiles();
        $this->replace($input ?? []);
    }

    protected function base64FileKeys(): array
    {
        return ['imagen'];
    }

    protected function imageRule()
    {
        $img = $this->method() === 'POST' ? 'required' : 'nullable';
        return [
            $img,
            'image',
            'mimes:webp,jpg,png',
            'dimensions:min_width=1080,min_height=1350'
        ];
    }

    private function normalizeTipoPromocion(mixed $value): string
    {
        if ($value instanceof TipoPromocion) {
            return $value->value;
        }

        if ($value === null || $value === '') {
            return TipoPromocion::GENERAL->value;
        }

        if (is_bool($value)) {
            return $value ? TipoPromocion::APP->value : TipoPromocion::GENERAL->value;
        }

        if (is_numeric($value)) {
            return ((int) $value) === 1 ? TipoPromocion::APP->value : TipoPromocion::GENERAL->value;
        }

        $normalized = strtolower(trim((string) $value));

        return match ($normalized) {
            '1', 'true' => TipoPromocion::APP->value,
            '0', 'false' => TipoPromocion::GENERAL->value,
            TipoPromocion::GENERAL->value,
            TipoPromocion::APP->value,
            TipoPromocion::AMBAS->value => $normalized,
            default => $normalized,
        };
    }
}
