<?php

declare(strict_types=1);

namespace app\admin\validate\split;

use app\admin\model\split\Link;
use app\admin\model\split\Ticket as TicketModel;
use think\Validate;

/**
 * 分流工单验证器（部署源文件，由 deploy_split_ticket.php 复制到 application）
 */
class Ticket extends Validate
{
    protected $rule = [
        'ticket_type'         => 'require|checkTicketType',
        'ticket_name'         => 'require|max:100',
        'ticket_url'          => 'require|max:1000',
        'ticket_total'        => 'require|integer|egt:0',
        'split_link_id'       => 'require|integer|gt:0|checkSplitLink',
        'number_type'         => 'require|checkNumberType',
        'number_type_custom'  => 'max:50|checkNumberTypeCustom',
        'start_time'          => 'require|checkStartTime',
        'end_time'            => 'require|checkEndTime',
        'order_limit'         => 'require|integer|egt:0',
        'assign_ratio'        => 'require|integer|egt:0',
        'account'             => 'max:50',
        'password'            => 'max:50',
    ];

    protected $message = [
        'ticket_type.require'   => '请选择工单类型',
        'ticket_name.require'   => '请填写工单名称',
        'ticket_name.max'       => '工单名称不能超过100个字符',
        'ticket_url.require'    => '请填写工单链接',
        'ticket_url.max'        => '工单链接不能超过1000个字符',
        'ticket_total.require'  => '请填写工单总量',
        'ticket_total.integer'  => '工单总量必须为整数',
        'ticket_total.egt'      => '工单总量不能小于0',
        'split_link_id.require' => '请选择分流链接',
        'number_type.require'   => '请选择号码类型',
        'start_time.require'    => '请选择开始时间',
        'end_time.require'      => '请选择到期时间',
        'order_limit.require'   => '请填写单号上限',
        'order_limit.egt'       => '单号上限不能小于0',
        'assign_ratio.require'  => '请填写下号比率',
        'assign_ratio.egt'      => '下号比率不能小于0',
    ];

    protected $scene = [
        'add'  => [
            'ticket_type', 'ticket_name', 'ticket_url', 'ticket_total', 'split_link_id',
            'number_type', 'number_type_custom', 'start_time', 'end_time',
            'order_limit', 'assign_ratio', 'account', 'password',
        ],
        'edit' => [
            'ticket_type', 'ticket_name', 'ticket_url', 'ticket_total', 'split_link_id',
            'number_type', 'number_type_custom', 'start_time', 'end_time',
            'order_limit', 'assign_ratio', 'account', 'password',
        ],
    ];

    /**
     * @param mixed $value
     * @return bool|string
     */
    protected function checkTicketType($value)
    {
        $key = (string) $value;
        $list = (new TicketModel())->getTicketTypeList();
        return isset($list[$key]) ? true : '工单类型无效';
    }

    /**
     * @param mixed $value
     * @return bool|string
     */
    protected function checkNumberType($value)
    {
        $key = (string) $value;
        $list = (new TicketModel())->getNumberTypeList();
        return isset($list[$key]) ? true : '号码类型无效';
    }

    /**
     * @param mixed $value
     * @param mixed $rule
     * @param array $data
     * @return bool|string
     */
    protected function checkNumberTypeCustom($value, $rule, array $data = [])
    {
        if (($data['number_type'] ?? '') !== 'custom') {
            return true;
        }
        if (trim((string) $value) === '') {
            return '请填写自定义号码类型';
        }
        return true;
    }

    /**
     * @param mixed $value
     * @param mixed $rule
     * @param array $data
     * @return bool|string
     */
    protected function checkSplitLink($value, $rule, array $data = [])
    {
        $linkId = (int) $value;
        $link = Link::get($linkId);
        if (!$link) {
            return '所选分流链接不存在';
        }
        if (($link['status'] ?? '') !== 'normal') {
            return '所选分流链接已停用';
        }
        return true;
    }

    /**
     * @param mixed $value
     * @return bool|string
     */
    protected function checkStartTime($value)
    {
        $ts = is_numeric($value) ? (int) $value : strtotime((string) $value);
        return ($ts !== false && $ts > 0) ? true : '开始时间格式无效';
    }

    /**
     * @param mixed $value
     * @param mixed $rule
     * @param array $data
     * @return bool|string
     */
    protected function checkEndTime($value, $rule, array $data = [])
    {
        $endTs = is_numeric($value) ? (int) $value : strtotime((string) $value);
        if ($endTs === false || $endTs <= 0) {
            return '到期时间格式无效';
        }
        $startRaw = $data['start_time'] ?? '';
        $startTs = is_numeric($startRaw) ? (int) $startRaw : strtotime((string) $startRaw);
        if ($startTs === false || $startTs <= 0) {
            return true;
        }
        if ($endTs <= $startTs) {
            return '到期时间必须晚于开始时间';
        }
        return true;
    }
}
