<?php

/**
 * 文件功能：节日福利活动创建请求
 *
 * 负责校验后台创建节日福利模板时提交的奖励、调度与目标用户字段。
 */

namespace App\Http\Requests;

use App\Rules\HolidayEventScheduleRule;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

/**
 * 类功能：校验创建节日福利模板的表单数据。
 */
class StoreHolidayEventRequest extends FormRequest
{
    /**
     * 判断当前用户是否允许提交创建请求。
     */
    public function authorize(): bool
    {
        return $this->user() !== null;
    }

    /**
     * 预处理布尔字段，避免浏览器复选框值造成类型偏差。
     */
    protected function prepareForValidation(): void
    {
        if ($this->has('enabled')) {
            $this->merge([
                'enabled' => $this->boolean('enabled'),
            ]);
        }
    }

    /**
     * 获取节日福利模板的字段校验规则。
     *
     * @return array<string, ValidationRule|array<int, ValidationRule|string>|string>
     */
    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'max:100'],
            'description' => ['nullable', 'string', 'max:500'],
            'total_amount' => ['required', 'integer', 'min:1'],
            'max_claimants' => ['required', 'integer', 'min:0'],
            'distribute_type' => ['required', Rule::in(['random', 'fixed'])],
            'min_amount' => ['nullable', 'integer', 'min:1', 'required_if:distribute_type,random'],
            'max_amount' => ['nullable', 'integer', 'min:1', 'gte:min_amount'],
            'fixed_amount' => ['nullable', 'integer', 'min:1', 'required_if:distribute_type,fixed'],
            'send_at' => ['nullable', 'date', Rule::requiredIf(fn (): bool => $this->input('repeat_type') !== 'yearly')],
            'expire_minutes' => ['required', 'integer', 'min:1', 'max:1440'],
            'repeat_type' => [
                'required',
                Rule::in(['once', 'daily', 'weekly', 'monthly', 'cron', 'yearly']),
                new HolidayEventScheduleRule,
            ],
            'cron_expr' => ['nullable', 'string', 'max:100', 'required_if:repeat_type,cron'],
            'schedule_month' => ['nullable', 'integer', 'between:1,12'],
            'schedule_day' => ['nullable', 'integer', 'between:1,31'],
            'schedule_time' => ['nullable', 'date_format:H:i'],
            'duration_days' => ['nullable', 'integer', 'min:1', 'max:31'],
            'daily_occurrences' => ['nullable', 'integer', 'min:1', 'max:24'],
            'occurrence_interval_minutes' => ['nullable', 'integer', 'min:1', 'max:1439'],
            'target_type' => ['required', Rule::in(['all', 'vip', 'level'])],
            'target_value' => ['nullable', 'string', 'max:50', 'required_if:target_type,level'],
            'enabled' => ['sometimes', 'boolean'],
        ];
    }

    /**
     * 获取中文错误提示。
     *
     * @return array<string, string>
     */
    public function messages(): array
    {
        return [
            'name.required' => '请输入活动名称',
            'total_amount.required' => '请填写总金币奖池',
            'max_claimants.required' => '请填写可领取人数上限',
            'distribute_type.required' => '请选择分配方式',
            'min_amount.required_if' => '随机分配模式下必须填写最低保底金额',
            'fixed_amount.required_if' => '定额发放模式下必须填写每人固定金额',
            'send_at.required' => '请选择触发时间',
            'expire_minutes.required' => '请填写领取有效期',
            'repeat_type.required' => '请选择重复方式',
            'cron_expr.required_if' => 'CRON 模式下必须填写表达式',
            'schedule_time.date_format' => '首轮开始时间格式必须为 HH:ii',
            'target_type.required' => '请选择目标用户范围',
            'target_value.required_if' => '指定等级以上模式下必须填写最低等级',
        ];
    }
}
