import { Descriptions, Space, Tag, Typography } from 'antd'
import { useEffect, useState } from 'react'

import type {
  CollectField,
  UploadedFile,
  WorkerAcceptance,
  WorkOrder,
} from '@/types/worker-platform'
import { getImageIdentity } from '@/utils/image-identity'

type DetailFieldItem = {
  key: string
  label: string
  required: boolean
  value: string
}

export function patchWorkOrderReadState(current: unknown, workOrderId: number) {
  if (!isRecord(current) || !isRecord(current.data) || !Array.isArray(current.data.items)) {
    return current
  }
  return {
    ...current,
    data: {
      ...current.data,
      items: current.data.items.map((item) =>
        isRecord(item) && Number(item.workOrderId) === workOrderId
          ? { ...item, isUnread: false }
          : item,
      ),
    },
  }
}

/** 好友赠送验收模式（整单，不参与拼单）。 */
export function isFriendGiftOrder(order: WorkOrder) {
  return order.acceptanceMode === 'friend_gift' && !order.myShare
}

export function getGiftPhaseMeta(phase: string): { label: string; color: string } {
  const metas: Record<string, { label: string; color: string }> = {
    material_required: { label: '待提交资料', color: 'orange' },
    material_submitted: { label: '待后台加好友', color: 'processing' },
    friend_countdown: { label: '赠送冷却中', color: 'gold' },
    gift_ready: { label: '可赠送', color: 'green' },
  }
  return metas[String(phase || '').trim()] || { label: String(phase || '-'), color: 'default' }
}

/** 好友赠送模式：待提交本人资料阶段。 */
export function canSubmitGiftMaterial(order: WorkOrder) {
  return (
    isFriendGiftOrder(order) &&
    ['in_progress', 'problem'].includes(order.status) &&
    order.gift?.phase === 'material_required'
  )
}

/** 好友赠送模式：冷却未结束前不能提交赠送凭证。 */
export function isGiftSubmissionBlocked(order: WorkOrder) {
  if (!isFriendGiftOrder(order)) return false
  if (!['in_progress', 'problem'].includes(order.status)) return false
  return order.gift?.phase !== 'gift_ready'
}

/** 好友赠送单进行中按赠送阶段展示状态，其他模式维持原状态文案。 */
export function getOrderStatusDisplay(order: WorkOrder): { label: string; color: string } {
  if (isFriendGiftOrder(order) && order.status === 'in_progress' && order.gift) {
    return getGiftPhaseMeta(order.gift.phase)
  }
  return { label: formatStatus(order.status), color: resolveStatusColor(order.status) }
}

/** 问题单来源与资料更新的订单角标，桌面表格与移动卡片共用。 */
export function getOrderFlagTags(order: WorkOrder) {
  const flags: Array<{ key: string; label: string; color: string }> = []
  if (order.problemMarked) flags.push({ key: 'problem', label: '平台标记', color: 'red' })
  if (order.pendingCancelRequest)
    flags.push({ key: 'cancel', label: '退单审核中', color: 'orange' })
  if (order.pendingFeedback) flags.push({ key: 'feedback', label: '反馈处理中', color: 'orange' })
  if (order.materialUpdated) flags.push({ key: 'material', label: '资料已更新', color: 'blue' })
  return flags
}

export function getOrderStatusHint(order: WorkOrder) {
  if (isFriendGiftOrder(order) && order.status === 'in_progress' && order.gift) {
    const hints: Record<string, string> = {
      material_required: '请提交本人游戏资料（昵称/ID/区服 + 主页截图），后台核对后添加好友。',
      material_submitted: '资料已提交，等待后台添加游戏好友并确认。',
      friend_countdown: '好友已添加，冷却结束后才能赠送。',
      gift_ready: '冷却已结束，赠送完成后请上传赠送凭证并提交验收。',
    }
    return hints[order.gift.phase] || getStatusHint(order.status)
  }
  return getStatusHint(order.status)
}

export function canSubmitAcceptance(order: WorkOrder) {
  if (order.myShare) {
    return order.myShare.status === 'joined' && order.status !== 'accepted'
  }
  if (isFriendGiftOrder(order)) {
    return ['in_progress', 'problem'].includes(order.status) && order.gift?.phase === 'gift_ready'
  }
  return ['in_progress', 'problem'].includes(order.status)
}

export function canRemindAcceptance(order: WorkOrder) {
  return !order.myShare && order.status === 'pending_acceptance'
}

export function canRequestCancel(order: WorkOrder) {
  if (order.myShare) {
    return (
      ['joined', 'submitted'].includes(order.myShare.status) &&
      ['open', 'pending_acceptance'].includes(order.status)
    )
  }
  return order.status === 'in_progress'
}

export function canSubmitFeedback(order: WorkOrder) {
  if (order.myShare) return order.myShare.status !== 'cancelled'
  return Boolean(order.assignedAt || order.worker)
}

export function canAutoAcceptOrder(order: WorkOrder, workerCanAutoAcceptWithoutEvidence: boolean) {
  // 好友赠送模式必须由后台人工验收赠送凭证，不适用 VIP 免审核直通。
  if (isFriendGiftOrder(order)) return false
  if (!workerCanAutoAcceptWithoutEvidence) return false
  if (order.myShare) return order.myShare.status === 'joined' && order.status !== 'accepted'
  return order.sharing?.enabled !== true && ['in_progress', 'problem'].includes(order.status)
}

export function canSupplementAcceptedEvidence(order: WorkOrder) {
  return order.status === 'accepted'
}

export function isVipEvidencePending(order: WorkOrder) {
  const acceptance = getWorkerAcceptance(order)
  return acceptance?.reviewMode === 'vip_auto' && acceptance?.evidenceStatus === 'pending'
}

/** 是否可编辑验收图片：未提交时可暂存，已提交时可补充或修改。 */
export function canEditAcceptanceImages(order: WorkOrder) {
  if (order.myShare) {
    return (
      ['joined', 'submitted'].includes(order.myShare.status) || canSupplementAcceptedEvidence(order)
    )
  }
  return (
    ['in_progress', 'problem', 'pending_acceptance'].includes(order.status) ||
    canSupplementAcceptedEvidence(order)
  )
}

/** 是否已提交验收：拼单依据份额状态，整单依据工单状态。 */
export function hasSubmittedAcceptance(order: WorkOrder) {
  if (order.myShare) {
    return order.myShare.status === 'submitted'
  }
  return order.status === 'pending_acceptance' || order.status === 'accepted'
}

export function getDisplayOrderNo(
  order: Pick<WorkOrder, 'platformOrderId'> | null | undefined,
): string {
  return String(order?.platformOrderId || '').trim() || '-'
}

export function getRequirementFields(order: WorkOrder | null): CollectField[] {
  if (!order) return []
  const rawFields = Array.isArray(order.requirement?.fields) ? order.requirement.fields : []
  return rawFields
    .map((item) => {
      const source = asRecord(item)
      const key = String(source.key || '').trim()
      if (!key) return null
      return {
        key,
        label: String(source.label || key).trim(),
        required: source.required !== false,
      }
    })
    .filter((item): item is CollectField => Boolean(item))
}

export function getMaterialFields(order: WorkOrder): Record<string, string> {
  const material = asRecord(order.material)
  const collect = asRecord(material.collect)
  const fields = asRecord(collect.fields || material.fields)
  return Object.fromEntries(
    Object.entries(fields).map(([key, value]) => [key, String(value || '')]),
  )
}

/** 把任意图片 Blob 转成 PNG，兼容 Chrome 剪贴板 API。 */
export async function toPngBlob(source: Blob): Promise<Blob> {
  const url = URL.createObjectURL(source)
  try {
    const image = await loadImageElement(url)
    const canvas = document.createElement('canvas')
    canvas.width = image.naturalWidth
    canvas.height = image.naturalHeight
    const context = canvas.getContext('2d')
    if (!context) return source
    const png = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, 'image/png'))
    return png || source
  } finally {
    URL.revokeObjectURL(url)
  }
}

export function getMaterialScreenshots(order: WorkOrder): UploadedFile[] {
  const material = asRecord(order.material)
  const collect = asRecord(material.collect)
  const screenshots = Array.isArray(collect.screenshots) ? collect.screenshots : []
  return screenshots
    .map((item) => {
      const file = asRecord(item)
      const url = String(file.url || '').trim()
      if (!url) return null
      return {
        objectKey: String(file.objectKey || file.object_key || '').trim(),
        filename: String(file.originalFilename || file.filename || '').trim(),
        url,
        mediumUrl: String(file.mediumUrl || file.medium_url || '').trim(),
        thumbnailUrl: String(file.thumbnailUrl || file.thumbnail_url || '').trim(),
      } as UploadedFile
    })
    .filter((item): item is UploadedFile => Boolean(item))
}

export function getMaterialDetailItems(order: WorkOrder): DetailFieldItem[] {
  const values = getMaterialFields(order)
  const requiredFields = getRequirementFields(order)
  const usedKeys = new Set<string>()
  const items = requiredFields.map((field) => {
    usedKeys.add(field.key)
    return {
      key: field.key,
      label: field.label,
      required: field.required,
      value: String(values[field.key] || ''),
    }
  })

  Object.entries(values).forEach(([key, value]) => {
    if (usedKeys.has(key)) return
    items.push({ key, label: key, required: false, value: String(value || '') })
  })
  return items
}

export function getCopyOrderInfoItems(
  order: WorkOrder,
): Array<Pick<DetailFieldItem, 'label' | 'value'>> {
  const productName = String(order.productName || '').trim()
  const materialItems = getMaterialDetailItems(order).filter((item) =>
    String(item.value || '').trim(),
  )
  return [...(productName ? [{ label: '物品', value: productName }] : []), ...materialItems]
}

export function renderDetailFieldValues(items: DetailFieldItem[], emptyText: string) {
  if (items.length === 0) {
    return <Typography.Text type="secondary">{emptyText}</Typography.Text>
  }
  return (
    <Descriptions column={1} bordered size="small">
      {items.map((item) => (
        <Descriptions.Item
          key={item.key}
          label={
            <Space size={6} wrap>
              <span>{item.label}</span>
              {item.required ? <Tag color="orange">必填</Tag> : null}
            </Space>
          }
        >
          <span className="worker-order-detail-value">
            {String(item.value || '').trim() || '-'}
          </span>
        </Descriptions.Item>
      ))}
    </Descriptions>
  )
}

/** 打手自己的验收资料，拼单时只读取其责任份额。 */
export function getWorkerAcceptance(
  order: WorkOrder | null | undefined,
): WorkerAcceptance | undefined {
  if (!order) return undefined
  return order.myShare ? order.myShare.acceptance : order.acceptance
}

/** 打手自己的暂存草稿，拼单时只读取其责任份额。 */
export function getWorkerDraft(order: WorkOrder | null | undefined): WorkerAcceptance | undefined {
  if (!order) return undefined
  return order.myShare?.draftAcceptance || order.draftAcceptance
}

export function getUniqueAcceptanceFiles(source?: WorkerAcceptance | null): UploadedFile[] {
  if (!source) return []
  const files = [
    ...(Array.isArray(source.files) ? source.files : []),
    ...(Array.isArray(source.imageUrls) ? source.imageUrls : []).map(
      (url): UploadedFile => ({
        objectKey: '',
        url: String(url || ''),
        thumbnailUrl: String(url || ''),
        mediumUrl: String(url || ''),
        filename: '图片',
        contentType: '',
        size: 0,
      }),
    ),
  ]
  const identities = new Set<string>()
  return files.filter((file) => {
    const identity = getImageIdentity(file)
    if (!identity || identities.has(identity)) return false
    identities.add(identity)
    return true
  })
}

export function getAcceptanceSubmittedAt(order: WorkOrder): string | null {
  if (order.myShare) return order.myShare.submittedAt
  const acceptanceSubmittedAt =
    typeof order.acceptance?.submittedAt === 'string' ? order.acceptance.submittedAt : null
  return order.submittedAt || acceptanceSubmittedAt || null
}

/** 好友赠送冷却倒计时：按分钟刷新，展示“X天X小时后可赠送”。 */
export function GiftCountdownTag({ giftAvailableAt }: { giftAvailableAt: string | null }) {
  const [now, setNow] = useState(() => Date.now())
  useEffect(() => {
    const timer = window.setInterval(() => setNow(Date.now()), 30_000)
    return () => window.clearInterval(timer)
  }, [])
  const targetMs = Date.parse(String(giftAvailableAt || ''))
  if (!Number.isFinite(targetMs)) return null
  const remaining = targetMs - now
  if (remaining <= 0) return <Tag color="green">可赠送</Tag>
  const hours = Math.ceil(remaining / 3_600_000)
  const days = Math.floor(hours / 24)
  const restHours = hours % 24
  return <Tag color="gold">{days > 0 ? `${days}天${restHours}小时` : `${hours}小时`}后可赠送</Tag>
}

export function asRecord(value: unknown): Record<string, unknown> {
  return value && typeof value === 'object' && !Array.isArray(value)
    ? (value as Record<string, unknown>)
    : {}
}

export function formatMoney(value: number | undefined) {
  return `￥${((Number(value || 0) || 0) / 100).toFixed(2)}`
}

export function getSettlementLabel(status: string) {
  if (status === 'accepted' || status === 'vip_evidence_pending') return '已结算'
  if (!status) return '结算合计'
  return '预计'
}

export function formatStatus(status: string) {
  const labels: Record<string, string> = {
    open: '已超时',
    in_progress: '代练中',
    pending_acceptance: '待验收',
    problem: '问题单',
    accepted: '已验收',
    cancelled: '已取消',
  }
  return labels[status] || status
}

export function getStatusHint(status: string) {
  const hints: Record<string, string> = {
    open: '任务已超时被系统判定失败，如需继续可前往大厅重新抢单。',
    in_progress: '订单进行中，完成后请及时提交验收资料。',
    pending_acceptance: '已提交验收，等待后台审核。',
    problem: '后台已标记问题，请根据备注调整后重新提交。',
    accepted: '订单已完成验收，可以在个人中心查看结算记录。',
    cancelled: '订单已取消，本次流程已结束。',
  }
  return hints[status] || '请关注当前订单状态变化。'
}

export function resolveStatusColor(status: string) {
  if (status === 'accepted') return 'green'
  if (status === 'cancelled') return 'default'
  if (status === 'problem') return 'red'
  if (status === 'pending_acceptance') return 'gold'
  if (status === 'open') return 'red'
  return 'blue'
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return Boolean(value && typeof value === 'object' && !Array.isArray(value))
}

function loadImageElement(src: string): Promise<HTMLImageElement> {
  return new Promise((resolve, reject) => {
    const image = new Image()
    image.onload = () => resolve(image)
    image.onerror = () => reject(new Error('图片解码失败'))
    image.src = src
  })
}
