import type { WorkOrderRow } from '../../repositories/worker-platform/index.js'
import type { JsonObject } from '../../types/json.js'
import { safeParseJson } from '../admin/admin-query-utils.js'

export type RequirementField = {
  key: string
  label: string
  required: boolean
  type: 'text' | 'select'
  options: string[]
  mockValue: string
}

export function resolveRequirementFields(workOrder: WorkOrderRow) {
  return normalizeRequirementFields(safeParseJson(workOrder.requirement_json).fields)
}

export function normalizeRequirementFields(value: unknown) {
  const rawFields = Array.isArray(value) ? value : []
  const fields = rawFields
    .map((item) => {
      const source =
        item && typeof item === 'object' && !Array.isArray(item) ? (item as JsonObject) : {}
      const key = String(source.key || '').trim()
      if (!key) return null
      const type = source.type === 'select' ? 'select' : 'text'
      const options = Array.isArray(source.options)
        ? source.options.map((option) => String(option || '').trim()).filter(Boolean)
        : []
      return {
        key,
        label: String(source.label || key).trim(),
        required: source.required !== false,
        type,
        options,
        mockValue: String(source.mockValue || '').trim(),
      }
    })
    .filter((item): item is RequirementField => Boolean(item))

  if (fields.length > 0 && !isDefaultTemplateRequirementFields(fields)) {
    return fields
  }
  return [
    {
      key: 'gameId',
      label: '游戏编号',
      required: true,
      type: 'text',
      options: [],
      mockValue: 'test_uid',
    },
    {
      key: 'gameNickname',
      label: '游戏昵称',
      required: true,
      type: 'text',
      options: [],
      mockValue: '测试角色',
    },
    {
      key: 'system',
      label: '系统',
      required: false,
      type: 'select',
      options: ['安卓', '苹果'],
      mockValue: '安卓',
    },
    {
      key: 'serverZone',
      label: '区服',
      required: false,
      type: 'select',
      options: ['QQ区', '微信区'],
      mockValue: 'QQ区',
    },
  ]
}

function isDefaultTemplateRequirementFields(fields: RequirementField[]): boolean {
  if (fields.length === 0) return true
  const defaultKeys = new Set(['gameId', 'gameNickname', 'system', 'serverZone'])
  const legacyKeys = new Set(['gameAccount', 'serverName', 'roleName'])
  return fields.every((field) => defaultKeys.has(field.key) || legacyKeys.has(field.key))
}

export function normalizeRequirementFieldsFromPayload(payload: JsonObject) {
  const directFields = Array.isArray(payload.fields) ? payload.fields : null
  const requirement =
    payload.requirement &&
    typeof payload.requirement === 'object' &&
    !Array.isArray(payload.requirement)
      ? (payload.requirement as JsonObject)
      : {}
  if (directFields) {
    return normalizeRequirementFields(directFields)
  }
  if (Array.isArray(requirement.fields)) {
    return normalizeRequirementFields(requirement.fields)
  }

  const textFields = normalizeRequirementFieldsText(
    payload.fieldsText || payload.requiredFieldsText,
  )
  return textFields.length > 0 ? textFields : normalizeRequirementFields([])
}

export function normalizeRequirementFieldsText(value: unknown) {
  return String(value || '')
    .split(/\r?\n/)
    .map((line, index) => {
      const text = line.trim()
      if (!text) return null
      const delimiter = text.includes('：') ? '：' : ':'
      if (text.includes(delimiter)) {
        const [rawKey, ...labelParts] = text.split(delimiter)
        const key = String(rawKey || '').trim()
        if (!key) return null
        const labelWithOptions = labelParts.join(delimiter).trim() || key
        const [label, rawOptions] = splitFieldOptions(labelWithOptions)
        return {
          key,
          label: label || key,
          required: true,
          type: rawOptions.length > 0 ? 'select' : 'text',
          options: rawOptions,
          mockValue: '',
        }
      }
      const [plainLabel, plainOptions] = splitFieldOptions(text)
      return {
        key: `field${index + 1}`,
        label: plainLabel,
        required: true,
        type: plainOptions.length > 0 ? 'select' : 'text',
        options: plainOptions,
        mockValue: '',
      }
    })
    .filter((item): item is RequirementField => Boolean(item))
}

function splitFieldOptions(value: string): [string, string[]] {
  const text = String(value || '').trim()
  if (!text.includes('#')) {
    return [text, []]
  }
  const [label, ...optionParts] = text.split('#')
  const options = optionParts
    .join('#')
    .split(/[,，、]/)
    .map((option) => String(option || '').trim())
    .filter(Boolean)
  return [String(label || '').trim(), options]
}
