import { ClockCircleOutlined, EyeOutlined, ReloadOutlined, SearchOutlined } from '@ant-design/icons'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import {
  Alert,
  App,
  Button,
  Card,
  Descriptions,
  Drawer,
  Empty,
  Input,
  InputNumber,
  Modal,
  Pagination,
  Space,
  Spin,
  Switch,
  Tabs,
  Tag,
  Tooltip,
  Typography,
} from 'antd'
import { useEffect, useState } from 'react'

import {
  fetchWorkerHallOrders,
  fetchWorkerMyOrders,
  fetchWorkerProfile,
  grabWorkerOrder,
  joinWorkerSharingOrder,
} from '@/services/worker'
import type { CollectField, WorkOrder, WorkerUser } from '@/types/worker-platform'
import { formatDateTime } from '@/utils/date-time'

type HallSummary = {
  activeCount: number
  pendingAcceptanceCount: number
  problemCount: number
}

export default function WorkerHallPage() {
  const { message } = App.useApp()
  const queryClient = useQueryClient()
  const [keywordInput, setKeywordInput] = useState('')
  const [keyword, setKeyword] = useState('')
  const [categoryId, setCategoryId] = useState(0)
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(20)
  const [grabbingId, setGrabbingId] = useState(0)
  const [detailOrder, setDetailOrder] = useState<WorkOrder | null>(null)
  const [sharingOrder, setSharingOrder] = useState<WorkOrder | null>(null)
  const [sharingQuantity, setSharingQuantity] = useState(1)
  const [submittingSharing, setSubmittingSharing] = useState(false)
  const [autoRefresh, setAutoRefresh] = useState(loadAutoRefreshPreference)

  useEffect(() => {
    if (!autoRefresh) return
    const timer = window.setInterval(() => {
      refreshAll()
    }, 5000)
    return () => window.clearInterval(timer)
  }, [autoRefresh])

  function toggleAutoRefresh(enabled: boolean) {
    setAutoRefresh(enabled)
    localStorage.setItem(AUTO_REFRESH_STORAGE_KEY, enabled ? '1' : '0')
  }

  const ordersQuery = useQuery({
    queryKey: ['worker-hall-orders', keyword, categoryId, page, pageSize],
    queryFn: () =>
      fetchWorkerHallOrders({ keyword, page, pageSize, categoryId: categoryId || undefined }),
    retry: false,
  })

  const profileQuery = useQuery({
    queryKey: ['worker-profile'],
    queryFn: () => fetchWorkerProfile(),
    retry: false,
  })

  const hallSummaryQuery = useQuery({
    queryKey: ['worker-hall-summary'],
    queryFn: async () => {
      const [inProgressResponse, pendingAcceptanceResponse, problemResponse] =
        await Promise.all([
          fetchWorkerMyOrders({
            status: 'in_progress',
            page: 1,
            pageSize: 1,
          }),
          fetchWorkerMyOrders({
            status: 'pending_acceptance',
            page: 1,
            pageSize: 1,
          }),
          fetchWorkerMyOrders({
            status: 'problem',
            page: 1,
            pageSize: 1,
          }),
        ])

      const pendingAcceptanceCount =
        pendingAcceptanceResponse.data.pagination.total
      const problemCount = problemResponse.data.pagination.total

      return {
        activeCount:
          inProgressResponse.data.pagination.total +
          pendingAcceptanceCount +
          problemCount,
        pendingAcceptanceCount,
        problemCount,
      } satisfies HallSummary
    },
    retry: false,
  })

  const orders = ordersQuery.data?.data.items || []
  const pagination = ordersQuery.data?.data.pagination
  const categories = ordersQuery.data?.data.categories || []
  const worker = profileQuery.data?.data.worker
  const activeCount = hallSummaryQuery.data?.activeCount || 0
  const pendingAcceptanceCount = hallSummaryQuery.data?.pendingAcceptanceCount || 0
  const problemCount = hallSummaryQuery.data?.problemCount || 0
  const maxActiveOrders = Number(worker?.level?.permissions.maxActiveOrders || 0)
  const remainingSlots =
    maxActiveOrders > 0 ? Math.max(0, maxActiveOrders - activeCount) : null
  const shouldWarn =
    (remainingSlots !== null && remainingSlots <= 0) || problemCount > 0
  const detailDisabledReason = detailOrder
    ? resolveGrabDisabledReason(detailOrder, worker, remainingSlots)
    : ''

  async function refreshAll() {
    await Promise.all([
      queryClient.invalidateQueries({ queryKey: ['worker-hall-orders'] }),
      queryClient.invalidateQueries({ queryKey: ['worker-hall-summary'] }),
      queryClient.invalidateQueries({ queryKey: ['worker-profile'] }),
      queryClient.invalidateQueries({ queryKey: ['worker-my-orders'] }),
      queryClient.invalidateQueries({ queryKey: ['worker-my-orders-overview'] }),
    ])
  }

  async function submitGrab(order: WorkOrder) {
    setGrabbingId(order.workOrderId)
    try {
      await grabWorkerOrder(order.workOrderId)
      message.success('抢单成功，已进入我的订单')
      setDetailOrder(null)
      await refreshAll()
    } catch (error) {
      message.error(error instanceof Error ? error.message : '抢单失败')
    } finally {
      setGrabbingId(0)
    }
  }

  function openSharingModal(order: WorkOrder) {
    setSharingOrder(order)
    setSharingQuantity(1)
  }

  async function submitSharing() {
    if (!sharingOrder) return
    setSubmittingSharing(true)
    try {
      await joinWorkerSharingOrder(sharingOrder.workOrderId, {
        quantity: sharingQuantity,
      })
      message.success('拼单成功，已进入我的订单')
      setSharingOrder(null)
      setDetailOrder(null)
      await refreshAll()
    } catch (error) {
      message.error(error instanceof Error ? error.message : '拼单失败')
    } finally {
      setSubmittingSharing(false)
    }
  }

  function resolveSharingRemaining(order: WorkOrder): number {
    const sharing = order.sharing
    if (!sharing?.enabled) return 0
    const progress = order.sharingProgress
    return Math.max(0, sharing.totalQuantity - (progress?.joinedQuantity || 0))
  }

  function resolveSharingDeposit(order: WorkOrder, quantity: number): number {
    const sharing = order.sharing
    if (!sharing?.enabled) return 0
    const deposit = Number(order.requiredDepositAmount || 0)
    const total = Math.max(1, sharing.totalQuantity)
    return Math.round((deposit * quantity) / total)
  }

  function applyKeywordSearch() {
    setKeyword(keywordInput.trim())
    setPage(1)
  }

  const summaryItems = [
    {
      label: '当前余额',
      value: worker ? formatMoney(worker.wallet.availableAmount) : '-',
      note: worker ? `冻结押金 ${formatMoney(worker.wallet.frozenDepositAmount)}` : '可用于抢单冻结',
    },
    {
      label: '接单上限',
      value:
        remainingSlots === null
          ? '未配置'
          : `${activeCount}/${maxActiveOrders} 单`,
      note:
        remainingSlots === null
          ? '当前等级待配置'
          : `待验收 ${pendingAcceptanceCount} 单 / 问题单 ${problemCount} 单`,
    },
  ]

  return (
    <section className="page-stack">
      <div className="worker-page-head">
        <Typography.Title level={3}>抢单大厅</Typography.Title>
        <Space wrap className="worker-hall-toolbar">
          <Button
            icon={<ReloadOutlined />}
            loading={
              ordersQuery.isFetching ||
              profileQuery.isFetching ||
              hallSummaryQuery.isFetching
            }
            onClick={() => refreshAll()}
          >
            刷新
          </Button>
          <Tooltip
            title={
              autoRefresh
                ? '已开启自动刷新，每 5 秒刷新一次，点击关闭'
                : '开启后每 5 秒自动刷新订单列表'
            }
          >
            <Switch
              size="small"
              checked={autoRefresh}
              onChange={toggleAutoRefresh}
            />
          </Tooltip>
          <Space.Compact className="worker-hall-search">
            <Input
              allowClear
              value={keywordInput}
              placeholder="搜索商品名称 / 订单号 / 工单号"
              prefix={<SearchOutlined />}
              onChange={(event) => {
                const nextKeyword = event.target.value
                setKeywordInput(nextKeyword)
                if (!nextKeyword.trim()) {
                  setKeyword('')
                  setPage(1)
                }
              }}
              onPressEnter={applyKeywordSearch}
            />
            <Button
              type="primary"
              icon={<SearchOutlined />}
              loading={ordersQuery.isFetching}
              onClick={applyKeywordSearch}
            >
              搜索
            </Button>
          </Space.Compact>
        </Space>
      </div>

      <Card className="worker-hall-board-card" bordered={false}>
        <div className="worker-hall-summary-strip">
          {summaryItems.map((item) => (
            <div key={item.label} className="worker-hall-summary-item">
              <span className="worker-hall-summary-label">{item.label}</span>
              <strong className="worker-hall-summary-value">{item.value}</strong>
              <small className="worker-hall-summary-note">{item.note}</small>
            </div>
          ))}
        </div>

        {categories.length > 0 ? (
          <Tabs
            size="small"
            activeKey={String(categoryId)}
            items={[
              { key: '0', label: '全部' },
              ...categories.map((category) => ({
                key: String(category.categoryId),
                label: category.name,
              })),
            ]}
            onChange={(nextKey) => {
              setCategoryId(Number(nextKey) || 0)
              setPage(1)
            }}
          />
        ) : null}

        {shouldWarn ? (
          <Alert
            className="worker-hall-warning"
            showIcon
            type="warning"
            message={
              remainingSlots !== null && remainingSlots <= 0
                ? '当前已达到接单上限，请先处理现有工单'
                : `当前还有 ${problemCount} 单问题单待处理，建议优先收口`
            }
          />
        ) : null}

        {ordersQuery.isLoading ? (
          <div className="worker-hall-loading">
            <Spin size="large" />
          </div>
        ) : ordersQuery.error ? (
          <Empty
            description={
              ordersQuery.error instanceof Error
                ? ordersQuery.error.message
                : '读取抢单大厅失败'
            }
          />
        ) : orders.length === 0 ? (
          <Empty
            description={
              keyword
                ? `没有找到与 “${keyword}” 相关的可抢工单`
                : '当前暂无可抢订单，可稍后刷新再看'
            }
          />
        ) : (
          <>
            <div className="worker-hall-card-grid">
              {orders.map((order) => {
                const disabledReason = resolveGrabDisabledReason(
                  order,
                  worker,
                  remainingSlots,
                )

                return (
                  <article key={order.workOrderId} className="worker-hall-card">
                    <div className="worker-hall-card-title">
                      <Typography.Link
                        className="worker-hall-card-link"
                        title={order.productName || order.workOrderNo}
                        onClick={() => setDetailOrder(order)}
                      >
                        {order.productName || order.workOrderNo}
                      </Typography.Link>
                      <Typography.Text type="secondary">
                        {order.categoryName || '默认分类'}
                      </Typography.Text>
                      <Typography.Text type="secondary">
                        订单号：{order.platformOrderId || order.workOrderNo}
                      </Typography.Text>
                    </div>

                    {order.sharing?.enabled ? (
                      <div className="worker-hall-card-sharing">
                        <Tag color="purple">拼单</Tag>
                        <Typography.Text type="secondary">
                          单价 {formatMoney(order.sharing.unitReward)} · 进度{' '}
                          {order.sharingProgress?.joinedQuantity || 0}/
                          {order.sharing.totalQuantity} · 剩{' '}
                          {resolveSharingRemaining(order)} 份
                        </Typography.Text>
                      </div>
                    ) : null}

                    {Number(order.timeoutMinutes || 0) > 0 ? (
                      <div className="worker-hall-card-sharing">
                        <Tag color="orange" icon={<ClockCircleOutlined />}>
                          限时 {order.timeoutMinutes} 分钟
                        </Tag>
                      </div>
                    ) : null}

                    <div className="worker-hall-card-amount-row">
                      <div className="worker-hall-card-amount">
                        {formatMoney(order.rewardAmount)}
                      </div>
                      <Typography.Text
                        type="secondary"
                        className="worker-hall-card-deposit"
                      >
                        所需保证金：{formatMoney(order.freezeDepositAmount)}
                      </Typography.Text>
                    </div>

                    {disabledReason ? (
                      <Typography.Text
                        type="danger"
                        className="worker-hall-card-hint"
                      >
                        {disabledReason}
                      </Typography.Text>
                    ) : null}

                    <div className="worker-hall-card-actions">
                      <div className="worker-hall-card-actions-row">
                        <Button
                          size="small"
                          type="text"
                          icon={<EyeOutlined />}
                          onClick={() => setDetailOrder(order)}
                        >
                          详情
                        </Button>
                      </div>
                      <div className="worker-hall-card-grab-row">
                        {order.sharing?.enabled ? (
                          <Button
                            type="primary"
                            size="large"
                            className="worker-hall-sharing-button"
                            disabled={Boolean(disabledReason) || Boolean(order.myShare)}
                            onClick={() => openSharingModal(order)}
                          >
                            {order.myShare
                              ? `已拼 ${order.myShare.quantity} 份`
                              : `拼单 ${formatMoney(order.sharing.unitReward)}/份`}
                          </Button>
                        ) : null}
                        <Button
                          type="primary"
                          size="large"
                          disabled={Boolean(disabledReason)}
                          loading={grabbingId === order.workOrderId}
                          onClick={() => submitGrab(order)}
                        >
                          {disabledReason || '立即抢单'}
                        </Button>
                      </div>
                    </div>
                  </article>
                )
              })}
            </div>

            {(pagination?.total || 0) > 0 ? (
              <div className="worker-hall-pagination">
                <Pagination
                  current={pagination?.page || page}
                  pageSize={pagination?.pageSize || pageSize}
                  total={pagination?.total || 0}
                  showSizeChanger
                  pageSizeOptions={[20, 50, 100]}
                  showTotal={(total) => `共 ${total} 条`}
                  onChange={(nextPage, nextPageSize) => {
                    setPage(nextPage)
                    setPageSize(nextPageSize)
                  }}
                />
              </div>
            ) : null}
          </>
        )}
      </Card>

      <Drawer
        title={
          detailOrder
            ? `${detailOrder.productName || '工单详情'} · ${detailOrder.workOrderNo}`
            : '工单详情'
        }
        width={760}
        open={Boolean(detailOrder)}
        destroyOnHidden
        onClose={() => setDetailOrder(null)}
        extra={
          detailOrder ? (
            <Button
              type="primary"
              disabled={Boolean(detailDisabledReason)}
              loading={grabbingId === detailOrder.workOrderId}
              onClick={() => submitGrab(detailOrder)}
            >
              立即抢单
            </Button>
          ) : null
        }
      >
        {detailOrder ? (
          <div className="worker-hall-detail-stack">
            <Alert
              showIcon
              type={detailDisabledReason ? 'warning' : 'success'}
              message={detailDisabledReason || buildGrabReadyHint(detailOrder)}
            />

            <Card title="基础信息" size="small">
              <Descriptions column={{ xs: 1, md: 2 }} bordered size="small">
                <Descriptions.Item label="商品">
                  {detailOrder.productName || '-'}
                </Descriptions.Item>
                <Descriptions.Item label="分类">
                  {detailOrder.categoryName || '-'}
                </Descriptions.Item>
                <Descriptions.Item label="工单号">
                  {detailOrder.workOrderNo}
                </Descriptions.Item>
                <Descriptions.Item label="平台订单号">
                  {detailOrder.platformOrderId || '-'}
                </Descriptions.Item>
                <Descriptions.Item label="接单奖励">
                  {formatMoney(detailOrder.rewardAmount)}
                </Descriptions.Item>
                <Descriptions.Item label="冻结押金">
                  {formatMoney(detailOrder.freezeDepositAmount)}
                </Descriptions.Item>
                <Descriptions.Item label="任务时限">
                  {Number(detailOrder.timeoutMinutes || 0) > 0 ? (
                    <Tag color="orange" icon={<ClockCircleOutlined />}>
                      限时 {detailOrder.timeoutMinutes} 分钟
                    </Tag>
                  ) : (
                    '不限时'
                  )}
                </Descriptions.Item>
                <Descriptions.Item label="发布时间">
                  {formatDateTime(resolvePublishedTime(detailOrder))}
                </Descriptions.Item>
                <Descriptions.Item label="更新时间">
                  {formatDateTime(detailOrder.updatedAt)}
                </Descriptions.Item>
                <Descriptions.Item label="资料要求">
                  {formatRequirementShortLabel(getRequirementFields(detailOrder))}
                </Descriptions.Item>
                <Descriptions.Item label="接单资格">
                  {detailDisabledReason || '当前可直接抢单'}
                </Descriptions.Item>
              </Descriptions>
            </Card>

            <Card title="资料要求" size="small">
              {renderRequirementFieldValues(detailOrder)}
            </Card>
          </div>
        ) : null}
      </Drawer>

      <Modal
        title={`拼单参与 · ${sharingOrder?.productName || ''}`}
        open={Boolean(sharingOrder)}
        confirmLoading={submittingSharing}
        onCancel={() => setSharingOrder(null)}
        onOk={submitSharing}
        okText="确认拼单"
        cancelText="取消"
        okButtonProps={{ disabled: sharingQuantity <= 0 }}
      >
        {sharingOrder ? (
          <Space direction="vertical" size={16} className="full-width">
            <Alert
              showIcon
              type="info"
              message={`单价 ${formatMoney(sharingOrder.sharing?.unitReward || 0)} / 份，剩余 ${resolveSharingRemaining(sharingOrder)} 份可拼`}
            />
            <Descriptions column={1} bordered size="small">
              <Descriptions.Item label="拼单进度">
                {sharingOrder.sharingProgress?.joinedQuantity || 0} /{' '}
                {sharingOrder.sharing?.totalQuantity || 0} 份
              </Descriptions.Item>
              <Descriptions.Item label="参与数量">
                <InputNumber
                  min={1}
                  max={resolveSharingRemaining(sharingOrder)}
                  value={sharingQuantity}
                  onChange={(value) => setSharingQuantity(Number(value) || 1)}
                  addonAfter="份"
                />
              </Descriptions.Item>
              <Descriptions.Item label="预估报酬">
                {formatMoney((sharingOrder.sharing?.unitReward || 0) * sharingQuantity)}
              </Descriptions.Item>
              <Descriptions.Item label="预估冻结押金">
                {formatMoney(resolveSharingDeposit(sharingOrder, sharingQuantity))}
              </Descriptions.Item>
            </Descriptions>
          </Space>
        ) : null}
      </Modal>
    </section>
  )
}

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))
}

function renderRequirementFieldValues(order: WorkOrder) {
  const fields = getRequirementFields(order)
  if (fields.length === 0) {
    return <Typography.Text type="secondary">当前工单未配置资料要求</Typography.Text>
  }

  return (
    <Descriptions column={1} bordered size="small">
      {fields.map((field) => (
        <Descriptions.Item key={field.key} label={field.label}>
          <Space size={6} wrap>
            <Typography.Text code>{field.key}</Typography.Text>
            <Tag color={field.required ? 'orange' : 'default'}>
              {field.required ? '必填' : '选填'}
            </Tag>
          </Space>
        </Descriptions.Item>
      ))}
    </Descriptions>
  )
}

function resolveGrabDisabledReason(
  order: WorkOrder,
  worker: WorkerUser | undefined,
  remainingSlots: number | null,
) {
  if (remainingSlots !== null && remainingSlots <= 0) {
    return '已达到当前等级最大同时接单量'
  }

  if (!worker) {
    return ''
  }

  const availableAmount = Number(worker.wallet.availableAmount || 0)
  const freezeAmount = Number(order.freezeDepositAmount || 0)
  if (availableAmount < freezeAmount) {
    return `余额不足，还差 ${formatMoney(freezeAmount - availableAmount)}`
  }

  return ''
}

function buildGrabReadyHint(order: WorkOrder) {
  const freezeAmount = Number(order.freezeDepositAmount || 0)
  if (freezeAmount <= 0) {
    return '当前工单无需冻结押金，可直接抢单'
  }
  return `抢单后会冻结 ${formatMoney(freezeAmount)}`
}

function formatRequirementShortLabel(fields: CollectField[]) {
  if (fields.length === 0) {
    return '资料简单'
  }
  const requiredCount = fields.filter((field) => field.required).length
  return `${requiredCount} 项必填 / 共 ${fields.length} 项`
}

function resolvePublishedTime(order: WorkOrder) {
  return order.publishedAt || order.createdAt || order.updatedAt
}

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

const AUTO_REFRESH_STORAGE_KEY = 'worker-hall-auto-refresh'

function loadAutoRefreshPreference(): boolean {
  return localStorage.getItem(AUTO_REFRESH_STORAGE_KEY) === '1'
}

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