import {
  CloseCircleOutlined,
  ReloadOutlined,
  SearchOutlined,
  SwapOutlined,
  UserSwitchOutlined,
} from '@ant-design/icons'
import {
  Alert,
  App,
  Button,
  Card,
  Form,
  Input,
  Select,
  Space,
  Table,
  Tag,
  Tooltip,
  Typography,
} from 'antd'
import type { TableColumnsType } from 'antd'
import { useQuery } from '@tanstack/react-query'
import { useMemo, useState } from 'react'
import { useNavigate, useSearchParams } from 'react-router'

import { AdminRangePicker } from '@/components/admin/AdminDatePicker'
import PageHeader from '@/components/admin/PageHeader'
import StatusTag from '@/components/admin/StatusTag'
import dayjs from '@/lib/dayjs'
import {
  closeAdminTask,
  fetchAdminTasks,
  markAdminTaskManualReview,
  rebindAdminTaskKuaishouCloudRole,
  retryAdminTask,
} from '@/services/admin'
import type { AdminTaskActionResponse, AdminTaskListItem } from '@/types/admin'
import { hasAdminRole } from '@/utils/admin-auth'
import { adminTaskStatusOptions } from '@/utils/admin-options'
import {
  ADMIN_DEFAULT_PAGE_SIZE,
  buildAdminTablePagination,
  resolveAdminPageSize,
} from '@/utils/admin-pagination'
import { formatAdminDateTime } from '@/utils/admin-time'

type TaskFilterForm = {
  status?: string
  platformOrderId?: string
  taskNo?: string
  skuCode?: string
  roleId?: string
  dateRange?: unknown
}

type TaskListAction = 'retry' | 'rebind_role' | 'manual_review' | 'close'
type TaskListBlocker = {
  label: string
  color: string
  level: 'normal' | 'error' | 'done'
  detail: string
  /** 列表副文案：完成态默认隐藏，异常/进行中显示 */
  showDetail: boolean
}

export default function AdminTasksPage() {
  const navigate = useNavigate()
  const { message, modal } = App.useApp()
  const [searchParams, setSearchParams] = useSearchParams()
  const [actionLoadingId, setActionLoadingId] = useState<number | null>(null)
  const [lastClaimUrl, setLastClaimUrl] = useState('')
  const page = Number(searchParams.get('page') || 1) || 1
  const pageSize = resolveAdminPageSize(searchParams.get('pageSize'), ADMIN_DEFAULT_PAGE_SIZE)
  const canManageTaskLifecycle = hasAdminRole('operator')
  // 与详情页一致：客服可换绑协助处理（canOperateAssistedTask）
  const canRebindRole = hasAdminRole('support')
  const canCloseTasks = hasAdminRole('support')
  const filters = {
    status: searchParams.get('status') || '',
    platformOrderId: searchParams.get('platformOrderId') || '',
    taskNo: searchParams.get('taskNo') || '',
    skuCode: searchParams.get('skuCode') || '',
    roleId: searchParams.get('roleId') || '',
    dateFrom: searchParams.get('dateFrom') || '',
    dateTo: searchParams.get('dateTo') || '',
  }

  const queryParams = useMemo(
    () => ({ page, pageSize, ...filters }),
    [
      filters.dateFrom,
      filters.dateTo,
      filters.platformOrderId,
      filters.roleId,
      filters.skuCode,
      filters.status,
      filters.taskNo,
      page,
      pageSize,
    ],
  )
  const query = useQuery({
    queryKey: ['admin-tasks', queryParams],
    queryFn: () => fetchAdminTasks(queryParams),
  })
  const data = query.data?.data

  const columns: TableColumnsType<AdminTaskListItem> = [
    {
      title: '任务 / 订单',
      minWidth: 210,
      render: (_, row) => (
        <div className="cell-stack">
          <Typography.Link onClick={() => navigate(`/admin/tasks/${row.taskId}`)}>
            {row.taskNo}
          </Typography.Link>
          <span className="muted">{row.platformOrderId}</span>
        </div>
      ),
    },
    {
      title: '商品',
      minWidth: 200,
      render: (_, row) => {
        const executor = resolveTaskExecutorDisplay(row.executorKey)

        return (
          <div className="cell-stack">
            <span>{row.skuName || '-'}</span>
            <span className="muted">{row.skuCode || '-'}</span>
            <Tag className="task-list-executor-tag" color={executor.color} title={executor.key}>
              {executor.label}
            </Tag>
          </div>
        )
      },
    },
    {
      title: '当前卡点',
      minWidth: 200,
      render: (_, row) => {
        const blocker = resolveTaskListBlocker(row)

        return (
          <div className="cell-stack">
            <Tag className="task-list-blocker-tag" color={blocker.color} title={blocker.detail}>
              {blocker.label}
            </Tag>
            {blocker.showDetail ? (
              <Typography.Text
                className="task-list-blocker-detail"
                type={blocker.level === 'error' ? 'danger' : 'secondary'}
                title={blocker.detail}
                ellipsis
              >
                {blocker.detail}
              </Typography.Text>
            ) : null}
          </div>
        )
      },
    },
    {
      title: '状态',
      minWidth: 120,
      render: (_, row) => (
        <Tooltip
          placement="topLeft"
          title={
            <div className="task-list-status-tooltip">
              <div className="task-list-status-tooltip-row">
                <span>交付</span>
                <StatusTag value={row.deliveryStatus} kind="delivery" />
              </div>
              <div className="task-list-status-tooltip-row">
                <span>资源</span>
                <StatusTag value={row.resourceStatus} kind="resource" />
              </div>
              <div className="task-list-status-tooltip-row">
                <span>客户</span>
                <StatusTag value={row.customerStatus} kind="customer" />
              </div>
            </div>
          }
        >
          <span className="task-list-status-main">
            <StatusTag value={row.status} kind="task" />
          </span>
        </Tooltip>
      ),
    },
    {
      title: '角色',
      minWidth: 140,
      render: (_, row) => (
        <div className="cell-stack">
          <span>{row.roleName || '-'}</span>
          {row.roleId || row.loginType ? (
            <span className="muted">{row.roleId || row.loginType}</span>
          ) : null}
        </div>
      ),
    },
    {
      title: '更新时间',
      minWidth: 160,
      render: (_, row) => (
        <span title={`创建 ${formatAdminDateTime(row.createdAt)}`}>
          {formatAdminDateTime(row.updatedAt)}
        </span>
      ),
    },
    {
      title: '操作',
      minWidth: 200,
      fixed: 'right',
      render: (_, row) => {
        const rowLoading = actionLoadingId === row.taskId
        const actionRunning = actionLoadingId !== null
        const canRetry =
          canManageTaskLifecycle &&
          row.executorKey !== 'manual_dispatch' &&
          ['retry_pending', 'manual_review'].includes(row.status)
        const canRebind = canRebindListTask(row, canRebindRole)
        const canManualReview =
          canManageTaskLifecycle &&
          !['redeemed', 'closed', 'completed', 'manual_review'].includes(row.status)
        const canClose = canCloseTasks && !['redeemed', 'closed'].includes(row.status)
        const hasActions = canRetry || canRebind || canManualReview || canClose

        return (
          <div className="cell-stack">
            {row.lastError ? (
              <Typography.Text type="danger" title={row.lastError} ellipsis>
                {row.lastError}
              </Typography.Text>
            ) : null}
            {hasActions ? (
              <Space size={[6, 6]} wrap>
                {canRetry ? (
                  <Button
                    size="small"
                    danger
                    ghost
                    icon={<ReloadOutlined />}
                    disabled={actionRunning}
                    loading={rowLoading}
                    onClick={() => handleActionCommand('retry', row)}
                  >
                    重试
                  </Button>
                ) : null}
                {canRebind ? (
                  <Button
                    size="small"
                    icon={<SwapOutlined />}
                    disabled={actionRunning}
                    loading={rowLoading}
                    onClick={() => handleActionCommand('rebind_role', row)}
                  >
                    换绑
                  </Button>
                ) : null}
                {canManualReview ? (
                  <Button
                    size="small"
                    icon={<UserSwitchOutlined />}
                    disabled={actionRunning}
                    loading={rowLoading}
                    onClick={() => handleActionCommand('manual_review', row)}
                  >
                    转人工
                  </Button>
                ) : null}
                {canClose ? (
                  <Button
                    size="small"
                    danger
                    icon={<CloseCircleOutlined />}
                    disabled={actionRunning}
                    loading={rowLoading}
                    onClick={() => handleActionCommand('close', row)}
                  >
                    关闭
                  </Button>
                ) : null}
              </Space>
            ) : (
              <span className="muted">—</span>
            )}
          </div>
        )
      },
    },
  ]

  function handleActionCommand(actionKey: TaskListAction, item: AdminTaskListItem) {
    const actionConfig = resolveTaskListAction(actionKey, item)

    modal.confirm({
      title: '确认操作',
      content: actionConfig.confirmText,
      okText: '继续执行',
      cancelText: '取消',
      centered: true,
      onOk: async () => {
        setActionLoadingId(item.taskId)
        try {
          const response = await actionConfig.action()
          if (response.data.claimUrl) {
            setLastClaimUrl(response.data.claimUrl)
          }
          message.success(actionConfig.successMessage)
          await query.refetch()
        } catch (error) {
          message.error(error instanceof Error ? error.message : '操作失败')
        } finally {
          setActionLoadingId(null)
        }
      },
    })
  }

  function resolveTaskListAction(
    actionKey: TaskListAction,
    item: AdminTaskListItem,
  ): {
    action: () => Promise<{ data: AdminTaskActionResponse }>
    confirmText: string
    successMessage: string
  } {
    if (actionKey === 'retry') {
      return {
        action: () => retryAdminTask(item.taskId),
        confirmText: `确认重试任务 ${item.taskNo} 吗？`,
        successMessage: '任务已重试',
      }
    }

    if (actionKey === 'rebind_role') {
      return {
        action: () => rebindAdminTaskKuaishouCloudRole(item.taskId),
        confirmText: `确认为任务 ${item.taskNo} 换绑角色吗？当前虚拟号会退还，并生成新的绑定二维码。`,
        successMessage: '角色换绑资源已准备完成',
      }
    }

    if (actionKey === 'manual_review') {
      return {
        action: () => markAdminTaskManualReview(item.taskId),
        confirmText: `确认将任务 ${item.taskNo} 转为人工处理吗？`,
        successMessage: '任务已转人工处理',
      }
    }

    return {
      action: () => closeAdminTask(item.taskId),
      confirmText: `确认关闭任务 ${item.taskNo} 吗？关闭后不会自动继续推进。`,
      successMessage: '任务已关闭',
    }
  }

  function applyFilters(values: TaskFilterForm) {
    const { dateRange, ...restValues } = values
    const [dateFrom, dateTo] = Array.isArray(dateRange)
      ? dateRange.map((item: { format?: (pattern: string) => string }) =>
          item?.format ? item.format('YYYY-MM-DD') : '',
        )
      : ['', '']

    setSearchParams(
      cleanParams({
        ...restValues,
        dateFrom,
        dateTo,
        page: 1,
        pageSize,
      }),
    )
  }

  function resetFilters() {
    setSearchParams(cleanParams({ page: 1, pageSize }))
  }

  return (
    <section className="page-stack">
      <PageHeader title="任务" description="跟踪履约任务状态、客户步骤和资源准备进度。" />

      <Card>
        <Form<TaskFilterForm>
          layout="inline"
          initialValues={{
            ...filters,
            dateRange:
              filters.dateFrom && filters.dateTo
                ? [dayjs(filters.dateFrom), dayjs(filters.dateTo)]
                : undefined,
          }}
          onFinish={applyFilters}
          className="filter-form"
        >
          <Form.Item name="status">
            <Select
              allowClear
              placeholder="任务状态"
              options={adminTaskStatusOptions}
              style={{ minWidth: 170 }}
            />
          </Form.Item>
          <Form.Item name="platformOrderId">
            <Input allowClear placeholder="平台订单号" />
          </Form.Item>
          <Form.Item name="taskNo">
            <Input allowClear placeholder="任务号" />
          </Form.Item>
          <Form.Item name="roleId">
            <Input allowClear placeholder="角色 ID" />
          </Form.Item>
          <Form.Item name="skuCode">
            <Input allowClear placeholder="商品名 / SKU" />
          </Form.Item>
          <Form.Item name="dateRange">
            <AdminRangePicker />
          </Form.Item>
          <Form.Item>
            <Space>
              <Button type="primary" icon={<SearchOutlined />} htmlType="submit">
                查询
              </Button>
              <Button icon={<ReloadOutlined />} onClick={resetFilters}>
                重置
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </Card>

      {lastClaimUrl ? (
        <Alert
          type="info"
          showIcon
          message="最近可用领取链接"
          description={
            <Typography.Text copyable={{ text: lastClaimUrl }}>{lastClaimUrl}</Typography.Text>
          }
        />
      ) : null}

      <Card>
        <Table<AdminTaskListItem>
          rowKey="taskId"
          loading={query.isLoading || query.isFetching}
          columns={columns}
          dataSource={data?.items || []}
          scroll={{ x: 1280 }}
          size="middle"
          rowClassName={(row) =>
            resolveTaskListBlocker(row).level === 'error' ? 'task-list-row-error' : ''
          }
          pagination={buildAdminTablePagination({
            current: data?.pagination.page || page,
            pageSize: data?.pagination.pageSize || pageSize,
            total: data?.pagination.total || 0,
            onChange: (nextPage, nextPageSize) => {
              setSearchParams(cleanParams({ ...filters, page: nextPage, pageSize: nextPageSize }))
            },
          })}
        />
      </Card>
    </section>
  )
}

function canRebindListTask(item: AdminTaskListItem, canRebindRole: boolean) {
  return (
    canRebindRole &&
    item.executorKey === 'kuaishou_ct_assisted' &&
    ['waiting_binding', 'role_confirmed', 'manual_review', 'retry_pending'].includes(item.status)
  )
}

function resolveTaskExecutorDisplay(value: unknown) {
  const executorKey = String(value || '').trim()
  if (executorKey === 'kuaishou_ct_assisted') {
    return { key: executorKey, label: '乐玩云', color: 'blue' }
  }
  if (executorKey === 'kuaishou-industry') {
    return { key: executorKey, label: '行业凭证', color: 'cyan' }
  }
  if (executorKey === 'kuaishou_feifei') {
    return { key: executorKey, label: '飞飞', color: 'purple' }
  }
  if (executorKey === 'manual_dispatch') {
    return { key: executorKey, label: '人工履约', color: 'orange' }
  }
  return {
    key: executorKey,
    label: executorKey || '未分配',
    color: 'default',
  }
}

function resolveTaskListBlocker(item: AdminTaskListItem): TaskListBlocker {
  const taskStatus = normalizeTaskListStatus(item.status)
  const deliveryStatus = normalizeTaskListStatus(item.deliveryStatus)
  const resourceStatus = normalizeTaskListStatus(item.resourceStatus)
  const customerStatus = normalizeTaskListStatus(item.customerStatus)
  const errorText = item.lastError || item.resultMessage

  if (
    ['completed', 'redeemed'].includes(taskStatus) ||
    ['delivered', 'completed', 'success', 'consumed'].includes(deliveryStatus)
  ) {
    return {
      label: '已完成',
      color: 'green',
      level: 'done',
      detail: item.resultMessage || '履约链路已完成。',
      showDetail: false,
    }
  }

  if (taskStatus === 'closed') {
    return {
      label: '已关闭',
      color: 'default',
      level: 'done',
      detail: item.resultMessage || item.lastError || '任务已关闭，不会继续自动推进。',
      showDetail: false,
    }
  }

  if (
    item.lastError ||
    ['manual_review', 'retry_pending', 'failed'].includes(taskStatus) ||
    ['resource_exception', 'binding_exception', 'failed'].includes(resourceStatus) ||
    ['customer_exception', 'failed'].includes(customerStatus) ||
    ['failed'].includes(deliveryStatus)
  ) {
    return {
      label: '需处理',
      color: 'red',
      level: 'error',
      detail: errorText || '需要进入详情页按履约层级检查并重试。',
      showDetail: true,
    }
  }

  if (item.executorKey === 'manual_dispatch') {
    return {
      label: '人工履约',
      color: 'orange',
      level: 'normal',
      detail: item.resultMessage || '等待人工回写履约结果。',
      showDetail: true,
    }
  }

  if (['pending_config'].includes(resourceStatus) || !item.executorKey) {
    return {
      label: '待配置',
      color: 'gold',
      level: 'normal',
      detail: item.resultMessage || '商品还没有命中明确的履约配置。',
      showDetail: true,
    }
  }

  if (
    [
      'not_started',
      'pending',
      'pending_prepare',
      'pending_binding',
      'pending_binding_prepare',
    ].includes(resourceStatus)
  ) {
    return {
      label: '等资源',
      color: 'gold',
      level: 'normal',
      detail: item.resultMessage || '等待准备履约资源，可在详情页触发对应动作。',
      showDetail: true,
    }
  }

  if (
    ['waiting_customer', 'waiting_binding', 'waiting_user_claim', 'user_binding'].includes(
      customerStatus,
    )
  ) {
    return {
      label: '等客户',
      color: 'blue',
      level: 'normal',
      detail: item.roleConfirmedAt
        ? '客户已提交角色信息，等待平台履约收口。'
        : '等待客户打开链接、绑定或提交信息。',
      showDetail: true,
    }
  }

  if (deliveryStatus && !['pending', 'not_started'].includes(deliveryStatus)) {
    return {
      label: '平台处理中',
      color: 'cyan',
      level: 'normal',
      detail: item.resultMessage || '平台履约执行中，可在详情页查看各层进度。',
      showDetail: true,
    }
  }

  return {
    label: '进行中',
    color: 'blue',
    level: 'normal',
    detail: item.resultMessage || '当前没有明确异常，等待任务自动推进。',
    showDetail: Boolean(item.resultMessage),
  }
}

function normalizeTaskListStatus(value: unknown) {
  return String(value || '')
    .trim()
    .toLowerCase()
}

function cleanParams(params: Record<string, unknown>) {
  const next = new URLSearchParams()
  Object.entries(params).forEach(([key, value]) => {
    const normalized = String(value ?? '').trim()
    if (normalized) {
      next.set(key, normalized)
    }
  })
  return next
}
