import type { ToastOptions, ModalOptions } from '@/types'

export interface ChooseMediaFile {
  tempFilePath: string
  fileType?: 'image' | 'video'
}

export interface ChooseMediaOptions {
  count?: number
  mediaType?: ('image' | 'video')[]
  sourceType?: string[]
  success?: (res: { tempFiles: ChooseMediaFile[] }) => void
  fail?: (err: any) => void
  complete?: () => void
}

/**
 * 兼容 uni.chooseMedia 在 H5 端不存在的问题
 * - 支持 chooseMedia 的环境直接使用
 * - H5 端降级为 uni.chooseImage / uni.chooseVideo
 */
export function chooseMediaCompat(options: ChooseMediaOptions): void {
  if (typeof uni.chooseMedia === 'function') {
    ;(uni as any).chooseMedia(options)
    return
  }

  const mediaType = options.mediaType || ['image', 'video']
  const onlyImage = mediaType.includes('image') && !mediaType.includes('video')
  const onlyVideo = mediaType.includes('video') && !mediaType.includes('image')

  if (onlyVideo && typeof uni.chooseVideo === 'function') {
    uni.chooseVideo({
      sourceType: options.sourceType,
      success: (res: any) => {
        options.success?.({
          tempFiles: [{ tempFilePath: res.tempFilePath, fileType: 'video' }],
        })
      },
      fail: options.fail,
      complete: options.complete,
    })
    return
  }

  // H5 端 chooseImage 支持多选，chooseVideo 仅支持单个
  // 当同时需要图片和视频时，为保证流程可用，默认按图片处理
  uni.chooseImage({
    count: options.count || 9,
    sourceType: options.sourceType,
    success: (res: any) => {
      const tempFiles = (res.tempFiles || res.tempFilePaths || []).map((f: any) => ({
        tempFilePath: f.path || f.tempFilePath || f,
        fileType: 'image' as const,
      }))
      options.success?.({ tempFiles })
    },
    fail: options.fail,
    complete: options.complete,
  })
}

/**
 * 安全隐藏原生 tabBar
 * 非 tabBar 页面调用会抛错，静默处理避免阻塞业务流程
 * App-PLUS 端原生 tabBar 可能延迟渲染，默认多 retry 几次
 */
export function safeHideTabBar(options?: { animation?: boolean; repeat?: number; interval?: number }): void {
  const animation = options?.animation ?? false
  const repeat = options?.repeat ?? 8
  const interval = options?.interval ?? 120

  function hideOnce() {
    try {
      const res = uni.hideTabBar({ animation, fail: () => {} }) as any
      if (res && typeof res.catch === 'function') {
        res.catch(() => {})
      }
    } catch {
      // ignore
    }
  }

  hideOnce()
  if (repeat > 1) {
    for (let i = 1; i < repeat; i++) {
      setTimeout(hideOnce, i * interval)
    }
  }
}

/**
 * 格式化日期时间
 */
export function formatDate(date: string | number | Date, format = 'YYYY-MM-DD HH:mm'): string {
  if (!date) return '-'
  const d = date instanceof Date ? date : new Date(date)
  if (isNaN(d.getTime())) return '-'

  const year = d.getFullYear()
  const month = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  const hour = String(d.getHours()).padStart(2, '0')
  const minute = String(d.getMinutes()).padStart(2, '0')
  const second = String(d.getSeconds()).padStart(2, '0')

  return format
    .replace('YYYY', String(year))
    .replace('MM', month)
    .replace('DD', day)
    .replace('HH', hour)
    .replace('mm', minute)
    .replace('ss', second)
}

/**
 * 格式化金额
 */
export function formatMoney(amount?: number | string | null): string {
  if (amount === undefined || amount === null || amount === '') return '-'
  const num = Number(amount)
  if (isNaN(num)) return '-'
  return '¥' + num.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
}

/**
 * 相对时间描述
 */
export function formatRelativeTime(value: string | number | Date): string {
  if (!value) return '-'
  const date = value instanceof Date ? value : new Date(value)
  const now = new Date()
  const diff = now.getTime() - date.getTime()
  const minute = 60 * 1000
  const hour = 60 * minute
  const day = 24 * hour

  if (diff < 0) return formatDate(value, 'MM-DD HH:mm')
  if (diff < minute) return '刚刚'
  if (diff < hour) return `${Math.floor(diff / minute)}分钟前`
  if (diff < day) return `${Math.floor(diff / hour)}小时前`
  if (diff < 7 * day) return `${Math.floor(diff / day)}天前`
  return formatDate(value, 'YYYY-MM-DD')
}

/**
 * 显示 Toast 提示
 */
export function showToast(options: ToastOptions | string): void {
  const opts: ToastOptions = typeof options === 'string' ? { title: options } : options
  uni.showToast({
    title: opts.title,
    icon: opts.icon || 'none',
    duration: opts.duration || 2000,
    mask: opts.mask ?? false
  })
}

/**
 * 隐藏 Toast
 */
export function hideToast(): void {
  uni.hideToast()
}

/**
 * 显示加载中
 */
export function showLoading(title = '加载中...'): void {
  uni.showLoading({ title, mask: true })
}

/**
 * 隐藏加载中
 */
export function hideLoading(): void {
  uni.hideLoading()
}

/**
 * 显示确认弹窗（简化版，返回 boolean）
 */
export function showConfirm(title: string, content?: string): Promise<boolean> {
  return new Promise((resolve) => {
    uni.showModal({
      title,
      content: content || '',
      showCancel: true,
      cancelText: '取消',
      confirmText: '确定',
      success: (res) => {
        resolve(res.confirm)
      }
    })
  })
}

/**
 * 显示确认弹窗
 */
export function showModal(options: ModalOptions | string): Promise<{ confirm: boolean; cancel: boolean }> {
  const opts: ModalOptions = typeof options === 'string' ? { content: options } : options
  return new Promise((resolve) => {
    uni.showModal({
      title: opts.title || '提示',
      content: opts.content,
      showCancel: opts.showCancel ?? true,
      cancelText: opts.cancelText || '取消',
      confirmText: opts.confirmText || '确定',
      success: (res) => {
        opts.success?.(res)
        resolve(res)
      }
    })
  })
}

/**
 * 本地存储
 */
export const storage = {
  get<T = unknown>(key: string, defaultValue?: T): T | undefined {
    try {
      const value = uni.getStorageSync(key)
      return value === '' ? defaultValue : (value as T)
    } catch {
      return defaultValue
    }
  },
  set(key: string, value: unknown): void {
    uni.setStorageSync(key, value)
  },
  remove(key: string): void {
    uni.removeStorageSync(key)
  },
  clear(): void {
    uni.clearStorageSync()
  }
}

/**
 * 模拟延迟
 */
export function delay(ms = 500): Promise<void> {
  return new Promise((resolve) => setTimeout(resolve, ms))
}

/**
 * 生成唯一 ID
 */
export function generateId(prefix = 'id'): string {
  return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
}

/**
 * 深拷贝
 */
export function deepClone<T>(obj: T): T {
  return JSON.parse(JSON.stringify(obj))
}

/**
 * 页面导航
 */
export function navigateTo(url: string): void {
  uni.navigateTo({ url })
}

export function redirectTo(url: string): void {
  uni.redirectTo({ url })
}

export function switchTab(url: string): void {
  // #ifdef APP-PLUS
  // App 端使用 reLaunch 兼容未配置原生 tabBar 的场景
  uni.reLaunch({ url })
  // #endif
  // #ifndef APP-PLUS
  uni.switchTab({ url })
  // #endif
}

export function goBack(delta = 1): void {
  uni.navigateBack({ delta })
}

/**
 * 任务状态文本
 */
export function getStatusText(status: string): string {
  const statusMap: Record<string, string> = {
    pending: '待审核',
    auditing: '待审核',
    approved: '待安排',
    assigned: '已安排',
    in_progress: '进行中',
    confirmed: '待排班',
    scheduled: '待出车',
    departed: '已出车',
    arrived: '已到达',
    constructing: '施工中',
    inspecting: '待验收',
    completed: '已完成',
    cancelled: '已取消',
    rejected: '已驳回'
  }
  return statusMap[status] || status
}

/**
 * 任务状态颜色
 */
export function getStatusColor(status: string): string {
  const colorMap: Record<string, string> = {
    pending: '#f59e0b',
    auditing: '#f59e0b',
    approved: '#2563eb',
    assigned: '#2563eb',
    in_progress: '#2563eb',
    confirmed: '#2563eb',
    scheduled: '#2563eb',
    departed: '#8b5cf6',
    arrived: '#10b981',
    constructing: '#2563eb',
    inspecting: '#f59e0b',
    completed: '#10b981',
    cancelled: '#ef4444',
    rejected: '#ef4444'
  }
  return colorMap[status] || '#6b7280'
}

/**
 * 任务状态背景色
 */
export function getStatusBgColor(status: string): string {
  const bgMap: Record<string, string> = {
    pending: '#fff7ed',
    auditing: '#fff7ed',
    approved: '#eff6ff',
    assigned: '#eff6ff',
    in_progress: '#eff6ff',
    confirmed: '#eff6ff',
    scheduled: '#eff6ff',
    departed: '#f3e8ff',
    arrived: '#ecfdf5',
    constructing: '#eff6ff',
    inspecting: '#fff7ed',
    completed: '#ecfdf5',
    cancelled: '#fef2f2',
    rejected: '#fef2f2'
  }
  return bgMap[status] || '#f5f5f5'
}

/**
 * 紧急程度文本
 */
export function getUrgentText(urgent: string): string {
  return urgent === 'high' ? '加急' : '普通'
}

/**
 * 任务类型文本
 */
export function getTypeText(type: string): string {
  const typeMap: Record<string, string> = {
    regular: '常规',
    emergency: '应急'
  }
  return typeMap[type] || type
}

/**
 * 角色文本
 */
export function getRoleText(role: string): string {
  const roleMap: Record<string, string> = {
    sales: '销售',
    dispatch: '调度',
    construction: '施工'
  }
  return roleMap[role] || role
}

/**
 * 车辆状态文本
 */
export function getVehicleStatusText(status: string): string {
  const map: Record<string, string> = {
    available: '可用',
    in_use: '使用中',
    maintenance: '维修中'
  }
  return map[status] || status
}

/**
 * 人员状态文本
 */
export function getPersonnelStatusText(status: string): string {
  const map: Record<string, string> = {
    idle: '空闲',
    working: '工作中',
    rest: '休息中',
    standby: '应急待命'
  }
  return map[status] || status
}

/**
 * 合作类型文本（后台 cooperation_type：annual/single/quarter/monthly）
 */
export function getCooperationTypeText(type: string | undefined | null): string {
  if (!type) return '-'
  const map: Record<string, string> = {
    annual: '包年',
    single: '单次',
    quarter: '季度',
    monthly: '月付'
  }
  return map[type] || type || '-'
}

/** @deprecated 兼容旧调用，等价于 getCooperationTypeText */
export function getProjectTypeText(type: string): string {
  return getCooperationTypeText(type)
}

/**
 * 所属行业文本（后台 industry 字典）
 */
export function getIndustryText(industry: string): string {
  const map: Record<string, string> = {
    residential: '住宅',
    commercial: '商业',
    industrial: '工业',
    municipal: '市政',
    medical: '医疗',
    education: '教育',
    catering: '餐饮'
  }
  return map[industry] || industry || '-'
}

import { useDictStore } from '@/stores/dict'

/**
 * 设施类型文本（项目：facility_type；任务：construction_facility）
 * 支持单值、逗号/顿号分隔、JSON 数组，并对常见英文 code 做兜底映射
 */
export function getFacilityTypeText(type: string | undefined | null): string {
  if (!type) return '-'

  const map: Record<string, string> = {
    septic_tank: '化粪池',
    direct_pump: '直抽直排',
    grease_pipe: '油污管+化粪池',
    pvc_pipe: 'PVC+化粪池',
    grease_pipe_septic_tank: '油污管+化粪池',
    pvc_pipe_septic_tank: 'PVC+化粪池'
  }

  function translateOne(raw: string): string {
    const key = raw.trim().toLowerCase().replace(/([a-z0-9])([A-Z])/g, '$1_$2').replace(/\s+/g, '_')
    if (!key) return ''
    if (map[key]) return map[key]

    const dictStore = useDictStore()
    const label = dictStore.getLabel('facility_type', key) || dictStore.getLabel('construction_facility', key)
    const isCodeLike = /^[a-z0-9_]+$/.test(label)
    if (label && label !== key && !isCodeLike) return label

    return map[key] || key
  }

  let items: string[] = []
  const normalized = String(type).trim()
  if (normalized.startsWith('[')) {
    try {
      const parsed = JSON.parse(normalized)
      items = Array.isArray(parsed) ? parsed.map(String) : [normalized]
    } catch {
      items = [normalized]
    }
  } else {
    items = normalized.split(/[,，、/]+/)
  }

  const translated = items.map(translateOne).filter(Boolean)
  return translated.length > 0 ? translated.join('、') : normalized
}

/**
 * 施工类型文本（construction_type 字典）
 */
export function getConstructionTypeText(type: string | undefined | null): string {
  if (!type) return '-'
  const dictStore = useDictStore()
  const label = dictStore.getLabel('construction_type', type)
  if (label && label !== type) return label

  const map: Record<string, string> = {
    dredge: '疏通',
    clean: '清掏',
    inspect: '排查',
    repair: '维修',
    emergency: '应急'
  }
  return map[type] || type
}

/**
 * 服务方式文本（service_method 字典）
 */
export function getServiceMethodText(value: string | undefined | null): string {
  if (!value) return '-'
  return useDictStore().getLabel('service_method', value)
}

/**
 * 建议出车文本（suggested_vehicle 字典）
 */
export function getSuggestedVehicleText(value: string | undefined | null): string {
  if (!value) return '-'
  return useDictStore().getLabel('suggested_vehicle', value)
}

/**
 * 取水距离文本（water_distance 字典）
 */
export function getWaterDistanceText(value: string | undefined | null): string {
  if (!value) return '-'
  return useDictStore().getLabel('water_distance', value)
}

/**
 * 验收方式文本（acceptance_method 字典）
 */
export function getAcceptanceMethodText(value: string | undefined | null): string {
  if (!value) return '-'
  return useDictStore().getLabel('acceptance_method', value)
}

/**
 * 解析后端以 JSON 字符串返回的数组字段（如 facilityTypes、servicePoints），容错返回数组
 */
export function parseJsonArray<T = any>(value: string | T[] | undefined | null): T[] {
  if (!value) return []
  if (Array.isArray(value)) return value
  try {
    const parsed = JSON.parse(value as string)
    return Array.isArray(parsed) ? parsed : []
  } catch (e) {
    return []
  }
}

/**
 * 解析位置联系人 JSON 字符串/数组
 */
export function parseLocationContacts(value: string | { name: string; phone: string }[] | undefined | null): { name: string; phone: string }[] {
  return parseJsonArray<{ name: string; phone: string }>(value)
}

/**
 * 将位置联系人数组序列化为 JSON 字符串
 */
export function formatLocationContacts(contacts: { name: string; phone: string }[]): string {
  return JSON.stringify(contacts || [])
}

/**
 * 项目状态文本（后台 project_status：pending/in_progress/completed/cancelled）
 */
export function getProjectStatusText(status: string): string {
  const map: Record<string, string> = {
    pending: '待启动',
    in_progress: '进行中',
    completed: '已完成',
    cancelled: '已取消'
  }
  return map[status] || status || '-'
}

export function getProjectStatusColor(status: string): string {
  const map: Record<string, string> = {
    pending: '#f59e0b',
    in_progress: '#2563eb',
    completed: '#10b981',
    cancelled: '#ef4444'
  }
  return map[status] || '#6b7280'
}

export function getProjectStatusBgColor(status: string): string {
  const map: Record<string, string> = {
    pending: '#fff7ed',
    in_progress: '#eff6ff',
    completed: '#ecfdf5',
    cancelled: '#fef2f2'
  }
  return map[status] || '#f3f4f6'
}

/**
 * 通知类型文本
 */
export function getNotificationTypeText(type: string): string {
  const map: Record<string, string> = {
    system: '系统',
    task: '任务',
    audit: '审核'
  }
  return map[type] || type
}

/**
 * 客户状态文本（1 合作中 / 0 已停用 / 2 潜在客户）
 */
export function getCustomerStatusText(status: number | string): string {
  const map: Record<string, string> = {
    1: '合作中',
    0: '已停用',
    2: '潜在客户'
  }
  return map[String(status)] || '-'
}

export function getCustomerStatusColor(status: number | string): string {
  const map: Record<string, string> = {
    1: '#10b981',
    2: '#2563eb',
    0: '#6b7280'
  }
  return map[String(status)] || '#6b7280'
}

export function getCustomerStatusBgColor(status: number | string): string {
  const map: Record<string, string> = {
    1: '#ecfdf5',
    2: '#eff6ff',
    0: '#f3f4f6'
  }
  return map[String(status)] || '#f3f4f6'
}

/**
 * 合同状态文本
 */
export function getContractStatusText(status: string): string {
  const map: Record<string, string> = {
    draft: '草稿',
    pending: '待生效',
    active: '生效中',
    expired: '已过期',
    terminated: '已终止'
  }
  return map[status] || status || '-'
}

export function getContractStatusColor(status: string): string {
  const map: Record<string, string> = {
    draft: '#6b7280',
    pending: '#f59e0b',
    active: '#10b981',
    expired: '#ef4444',
    terminated: '#ef4444'
  }
  return map[status] || '#6b7280'
}

export function getContractStatusBgColor(status: string): string {
  const map: Record<string, string> = {
    draft: '#f3f4f6',
    pending: '#fff7ed',
    active: '#ecfdf5',
    expired: '#fef2f2',
    terminated: '#fef2f2'
  }
  return map[status] || '#f3f4f6'
}

/**
 * 付款方式文本
 */
export function getPaymentMethodText(method: string): string {
  const map: Record<string, string> = {
    lump_sum: '一次性',
    installment: '分期'
  }
  return map[method] || method || '-'
}

/**
 * 解析 extraData 扩展字段 JSON 字符串，容错返回对象
 */
export function parseExtraData<T = Record<string, any>>(value?: string | T | null): T {
  if (!value) return {} as T
  if (typeof value !== 'string') return value as T
  try {
    return JSON.parse(value) as T
  } catch {
    return {} as T
  }
}

/**
 * 将任务日志操作类型/内容转换为展示文本
 */
export function formatTaskLogAction(operationType: string | undefined, operation: string | undefined): string {
  if (!operationType && !operation) return '状态更新'

  // 优先使用 operation 中的中文描述（后端已映射）
  if (operation && !operation.startsWith('执行SOP步骤')) {
    return operation
  }

  // SOP 步骤："执行SOP步骤: xxx，动作: execute" → "完成：xxx"
  if (operation && operation.startsWith('执行SOP步骤')) {
    const match = operation.match(/执行SOP步骤:\s*([^，]+)/)
    if (match) return `完成：${match[1].trim()}`
  }

  const map: Record<string, string> = {
    create: '创建任务',
    audit: '审核任务',
    dispatch: '任务分配',
    confirm: '确认接单',
    depart: '出车出发',
    arrive: '到达现场',
    work: '开始施工',
    complete: '完成任务',
    clean: '现场清理',
    accept: '客户验收',
    finish: '任务结案',
    urge: '催单',
    cancel: '取消任务',
    sop_next: 'SOP推进',
    sop_prev: 'SOP回退',
    departure_prep: '出车准备',
    site_survey: '现场勘察',
  }
  return map[operationType || ''] || operation || operationType || '状态更新'
}

/**
 * 根据任务日志操作类型判断角色
 */
export function getTaskLogRole(operationType: string | undefined): string {
  const map: Record<string, string> = {
    create: 'sales',
    audit: 'dispatch',
    dispatch: 'dispatch',
    urge: 'sales',
    cancel: 'sales',
  }
  return map[operationType || ''] || 'construction'
}

