<?php

declare(strict_types=1);

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

final class ReserveRequest extends FormRequest
{
    public function rules(): array
    {
        $action = $this->routeAction();

        if ($action === 'index') {
            return [
                'sort' => ['nullable', 'string'],
                'sort_type' => ['nullable', 'in:asc,desc'],
                'user_id' => ['nullable', 'string'],
                'park_id' => ['nullable', 'integer'],
                'reserve_date_from' => ['nullable', 'date'],
                'reserve_date_to' => ['nullable', 'date'],
                'keyword' => ['nullable', 'string'],
                'valid_flag' => ['nullable', 'in:0,1'],
            ];
        }

        if ($action === 'destroy') {
            return [
                'ids' => ['required'],
            ];
        }

        if ($action === 'store') {
            return [
                'user_id' => ['required', 'integer'],
                'park_id' => ['required', 'integer'],
                'contract_id' => ['nullable', 'string'],
                'price_parkplaceid' => ['nullable', 'integer'],
                'psection_id' => ['nullable', 'integer'],
                'reserve_date' => ['nullable', 'date'],
                'valid_flag' => ['nullable', 'in:0,1'],
            ];
        }

        if ($action === 'update') {
            return [
                'user_id' => ['required', 'integer'],
                'park_id' => ['required', 'integer'],
                'contract_id' => ['nullable', 'string'],
                'price_parkplaceid' => ['nullable', 'integer'],
                'psection_id' => ['nullable', 'integer'],
                'reserve_date' => ['nullable', 'date'],
                'reserve_start' => ['nullable', 'date'],
                'reserve_end' => ['nullable', 'date'],
                'valid_flag' => ['nullable', 'in:0,1'],
                'ope_id' => ['nullable', 'integer'],
            ];
        }

        // create/edit 등 “画面表示だけ” 는 검증 불필요
        return [];
    }

    /**
     * Why: Controller/Service 에서 공통으로 쓰는 입력 정규화.
     */
    public function payload(): array
    {
        $action = $this->routeAction();

        if ($action === 'index') {
            return [
                'sort' => (string) $this->input('sort', 'reserve_id'),
                'sortType' => (string) $this->input('sort_type', 'asc'),
                'userId' => trim((string) $this->input('user_id', '')),
                'parkId' => $this->filled('park_id') ? (int) $this->input('park_id') : null,
                'fromDt' => $this->input('reserve_date_from'),
                'toDt' => $this->input('reserve_date_to'),
                'keyword' => trim((string) $this->input('keyword', '')),
                'validFlag' => $this->filled('valid_flag') ? (string) $this->input('valid_flag') : null,
            ];
        }

        if ($action === 'destroy') {
            return [
                'ids' => $this->normalizeIds($this->input('ids')),
            ];
        }

        if ($action === 'store' || $action === 'update') {
            return [
                'contractId' => $this->input('contract_id'),
                'userCategoryId' => $this->filled('user_categoryid') ? (int) $this->input('user_categoryid') : null,
                'contractCreatedAt' => $this->input('contract_created_at'),

                'userId' => (int) $this->input('user_id'),
                'parkId' => (int) $this->input('park_id'),

                'priceParkplaceId' => $this->filled('price_parkplaceid') ? (int) $this->input('price_parkplaceid') : null,
                'psectionId' => $this->filled('psection_id') ? (int) $this->input('psection_id') : null,
                'ptypeId' => $this->filled('ptype_id') ? (int) $this->input('ptype_id') : null,

                'reserveDate' => $this->input('reserve_date'),
                'reserveStart' => $this->input('reserve_start'),
                'reserveEnd' => $this->input('reserve_end'),

                'reserveReduction' => $this->input('reserve_reduction'),
                'reserveAutoRemind' => $this->input('reserve_auto_remind'),
                'reserveManualRemind' => $this->input('reserve_manual_remind'),

                'flag800m' => $this->filled('800m_flag') ? (int) $this->input('800m_flag') : null,
                'reserveCancelday' => $this->input('reserve_cancelday'),

                'validFlag' => $this->filled('valid_flag') ? (int) $this->input('valid_flag') : null,

                'reserveManual' => $this->filled('reserve_manual') ? (int) $this->input('reserve_manual') : null,
                'reserveNotice' => $this->input('reserve_notice'),
                
                'sentDate' => $this->input('sent_date'),
                'reserveOrder' => $this->filled('reserve_order') ? (int) $this->input('reserve_order') : null,

                'reserveType' => $this->filled('reserve_type') ? (int) $this->input('reserve_type') : null,

                'opeId' => $this->filled('ope_id') ? (int) $this->input('ope_id') : null,
            ];
        }


        return [];
    }

    private function routeAction(): string
    {
        // routes: reserves.index / reserves.store / reserves.update / reserves.destroy ...
        $name = (string) $this->route()?->getName();
        if ($name === '') {
            return '';
        }

        $parts = explode('.', $name);
        return (string) end($parts);
    }

    private function normalizeIds(mixed $raw): array
    {
        if (is_string($raw)) {
            $raw = explode(',', $raw);
        }

        if (is_array($raw) && count($raw) === 1 && is_string($raw[0]) && str_contains($raw[0], ',')) {
            $raw = explode(',', $raw[0]);
        }

        $ids = array_map('intval', (array) $raw);
        $ids = array_values(array_unique(array_filter($ids, static fn (int $v): bool => $v > 0)));

        return $ids;
    }
}
