import type { Attachment } from '@/types/chat'

/** 工作流 form_input 支持的字段类型 */
export const WORKFLOW_FIELD_TYPE = {
  TEXT: 'text',
  SELECT: 'select',
  FILE: 'file',
} as const

export type WorkflowFieldType = typeof WORKFLOW_FIELD_TYPE[keyof typeof WORKFLOW_FIELD_TYPE] | string

/** 提交提问接口 paramMap：key 为 fieldList[].key；text/select 为 string，file 为 URL 数组 */
export type WorkflowParamMap = Record<string, string | string[]>

export interface WorkflowFieldOption {
  id?: string
  text?: string
  type?: string
}

/** 归一化后的表单字段（来自 cardList[].content.fieldList） */
export interface WorkflowFormField {
  key: string
  label: string
  type: WorkflowFieldType
  required: boolean
  multiple?: boolean
  options?: WorkflowFieldOption[]
  /** 接口预填（如已上传文档 URL） */
  presetValue?: string
}

export type WorkflowFormValues = Record<string, string | string[]>

export interface WorkflowFileSelection {
  fileName: string
  file?: File
  /** 上传接口返回的文件访问 URL，写入 paramMap[field.key] */
  fileUrls: string[]
}

export function isSupportedWorkflowFieldType(type: string | undefined): boolean {
  const normalized = String(type ?? '').trim().toLowerCase()
  return normalized === WORKFLOW_FIELD_TYPE.TEXT
    || normalized === WORKFLOW_FIELD_TYPE.SELECT
    || normalized === WORKFLOW_FIELD_TYPE.FILE
}

function isHttpUrl(value: string): boolean {
  return /^https?:\/\//i.test(value.trim())
}

/** 从 card-workflow 附件解析可渲染字段（保持 fieldList 顺序） */
export function parseWorkflowFormFields(attachment: Attachment): WorkflowFormField[] {
  const rawList = attachment.content?.fieldList
  if (!Array.isArray(rawList))
    return []

  return rawList
    .filter(field => Boolean(field?.key) && Boolean(field?.type) && isSupportedWorkflowFieldType(field.type))
    .map(field => ({
      key: String(field.key).trim(),
      label: String(field.label ?? field.key).trim(),
      type: String(field.type).trim().toLowerCase(),
      required: field.required === true,
      multiple: field.multiple === true,
      options: field.options,
      presetValue: field.value != null ? String(field.value).trim() : undefined,
    }))
}

export function isWorkflowFormAttachment(attachment: Attachment): boolean {
  return attachment?.type === 'card-workflow'
    && attachment?.content?.name === 'form_input'
    && parseWorkflowFormFields(attachment).length > 0
}

export function createInitialWorkflowFormValues(
  fields: WorkflowFormField[],
  options?: { searchParams?: URLSearchParams, useQueryPreset?: boolean },
): WorkflowFormValues {
  const initial: WorkflowFormValues = {}
  const searchParams = options?.searchParams
  const useQuery = options?.useQueryPreset === true && searchParams

  fields.forEach((field) => {
    if (field.type === WORKFLOW_FIELD_TYPE.SELECT && field.multiple) {
      if (useQuery) {
        const queryValue = searchParams!.get(field.key)
        initial[field.key] = queryValue
          ? queryValue.split(',').map(item => item.trim()).filter(Boolean)
          : []
      }
      else {
        initial[field.key] = []
      }
      return
    }

    if (useQuery) {
      const queryValue = searchParams!.get(field.key)
      initial[field.key] = queryValue ?? field.presetValue ?? ''
      return
    }

    initial[field.key] = field.presetValue ?? ''
  })

  return initial
}

export function createInitialWorkflowFileSelections(
  fields: WorkflowFormField[],
): Record<string, WorkflowFileSelection | undefined> {
  const selections: Record<string, WorkflowFileSelection | undefined> = {}
  fields.forEach((field) => {
    if (field.type !== WORKFLOW_FIELD_TYPE.FILE)
      return
    const preset = field.presetValue
    if (preset && isHttpUrl(preset)) {
      selections[field.key] = {
        fileName: preset.split('/').pop() || preset,
        fileUrls: [preset],
      }
    }
  })
  return selections
}

export function isWorkflowFieldFilled(
  field: WorkflowFormField,
  value: string | string[] | undefined,
  fileSelection?: WorkflowFileSelection,
): boolean {
  if (field.type === WORKFLOW_FIELD_TYPE.FILE) {
    if ((fileSelection?.fileUrls?.length ?? 0) > 0)
      return true
    if (field.presetValue && isHttpUrl(field.presetValue))
      return true
    return false
  }
  if (field.type === WORKFLOW_FIELD_TYPE.SELECT && field.multiple) {
    return Array.isArray(value) && value.length > 0
  }
  if (typeof value === 'string')
    return value.trim() !== ''
  return false
}

export function getWorkflowRequiredMissingFields(
  fields: WorkflowFormField[],
  values: WorkflowFormValues,
  fileSelections: Record<string, WorkflowFileSelection | undefined>,
): WorkflowFormField[] {
  return fields.filter(
    field => field.required && !isWorkflowFieldFilled(field, values[field.key], fileSelections[field.key]),
  )
}

function buildTextOrSelectParamValue(field: WorkflowFormField, value: string | string[] | undefined): string {
  if (field.type === WORKFLOW_FIELD_TYPE.SELECT && field.multiple) {
    return Array.isArray(value) ? value.join(',') : ''
  }
  return typeof value === 'string' ? value : ''
}

function buildFileParamValue(
  field: WorkflowFormField,
  fileSelection?: WorkflowFileSelection,
): string[] {
  const urls = fileSelection?.fileUrls?.filter(url => url.trim()) ?? []
  if (urls.length > 0)
    return urls
  if (field.presetValue && isHttpUrl(field.presetValue))
    return [field.presetValue]
  return []
}

/**
 * 按 cardList.fieldList 的 key 构建 paramMap（与 submit_question_stream 约定一致）
 * - text / select → string（未填为 ""）
 * - file → string[]（未填为 []，已上传为 ["http://..."]）
 */
export function buildWorkflowParamMap(
  fields: WorkflowFormField[],
  values: WorkflowFormValues,
  fileSelections: Record<string, WorkflowFileSelection | undefined>,
): WorkflowParamMap {
  const paramMap: WorkflowParamMap = {}
  fields.forEach((field) => {
    if (field.type === WORKFLOW_FIELD_TYPE.FILE)
      paramMap[field.key] = buildFileParamValue(field, fileSelections[field.key])
    else
      paramMap[field.key] = buildTextOrSelectParamValue(field, values[field.key])
  })
  return paramMap
}

/** 解析上传接口返回中的文件 URL */
export function extractUploadUrlFromResponse(data: unknown): string {
  if (typeof data === 'string' && data.trim())
    return data.trim()
  if (Array.isArray(data)) {
    const first = data.find(item => typeof item === 'string' && item.trim())
    return typeof first === 'string' ? first.trim() : ''
  }
  if (data && typeof data === 'object') {
    const record = data as Record<string, unknown>
    for (const key of ['url', 'fileUrl', 'docUrl', 'path', 'filePath']) {
      const candidate = record[key]
      if (typeof candidate === 'string' && candidate.trim())
        return candidate.trim()
    }
    if (Array.isArray(record.urlList)) {
      return extractUploadUrlFromResponse(record.urlList)
    }
  }
  return ''
}

/**
 * 构建 paramMap；若 file 已选本地文件但未上传，会先调用 uploadFile 再写入 URL 数组
 */
export async function buildWorkflowParamMapAsync(
  fields: WorkflowFormField[],
  values: WorkflowFormValues,
  fileSelections: Record<string, WorkflowFileSelection | undefined>,
  uploadFile?: (file: File) => Promise<string>,
): Promise<WorkflowParamMap> {
  const nextSelections = { ...fileSelections }

  for (const field of fields) {
    if (field.type !== WORKFLOW_FIELD_TYPE.FILE || !uploadFile)
      continue
    const selection = nextSelections[field.key]
    if (!selection?.file || (selection.fileUrls?.length ?? 0) > 0)
      continue
    const url = await uploadFile(selection.file)
    if (url) {
      nextSelections[field.key] = {
        ...selection,
        fileUrls: [url],
      }
    }
  }

  return buildWorkflowParamMap(fields, values, nextSelections)
}

export function getWorkflowFieldValidationMessage(field: WorkflowFormField): string {
  if (field.type === WORKFLOW_FIELD_TYPE.FILE)
    return `请上传${field.label.replace(/（可选）|\(可选\)/g, '').trim() || '文件'}`
  if (field.type === WORKFLOW_FIELD_TYPE.SELECT)
    return `请选择${field.label}`
  return `请填写${field.label}`
}
