import { ReloadOutlined } from '@ant-design/icons'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import {
  App,
  Alert,
  Button,
  Card,
  Form,
  Input,
  InputNumber,
  Modal,
  Select,
  Space,
  Table,
  Tag,
  Typography,
} from 'antd'
import { forwardRef, useImperativeHandle, useState } from 'react'

import ImageUpload from '@/components/files/ImageUpload'
import ImagePreviewList from '@/components/files/ImagePreviewList'
import {
  createAdminAfterSalesCase,
  fetchAdminAfterSalesCases,
  fetchAdminWorkOrderSharing,
  resolveAdminAfterSalesCase,
} from '@/services/admin'
import type { UploadedFile, WorkerAfterSalesCase, WorkOrder } from '@/types/worker-platform'
import { ADMIN_DEFAULT_PAGE_SIZE, buildAdminTablePagination } from '@/utils/admin-pagination'
import { formatAdminDateTime } from '@/utils/admin-time'
import { uniqueUploadedFiles } from '@/utils/image-identity'
import { asRecord, formatMoney } from './shared'

type AfterSalesCreateFormValues = {
  shareId?: number
  problemType?: string
  complaintNote?: string
}

type AfterSalesResolutionFormValues = {
  action?: 'not_upheld' | 'remedied' | 'upheld'
  resolutionNote?: string
  recoveryAmount?: number
}

export type AfterSalesPanelHandle = {
  openCreateModal: (row: WorkOrder) => void
}

const AfterSalesPanel = forwardRef<AfterSalesPanelHandle>(function AfterSalesPanel(_, ref) {
  const { message } = App.useApp()
  const queryClient = useQueryClient()
  const [afterSalesOrder, setAfterSalesOrder] = useState<WorkOrder | null>(null)
  const [afterSalesCase, setAfterSalesCase] = useState<WorkerAfterSalesCase | null>(null)
  const [afterSalesFiles, setAfterSalesFiles] = useState<UploadedFile[]>([])
  const [afterSalesPage, setAfterSalesPage] = useState(1)
  const [afterSalesPageSize, setAfterSalesPageSize] = useState(ADMIN_DEFAULT_PAGE_SIZE)
  const [afterSalesCreateForm] = Form.useForm<AfterSalesCreateFormValues>()
  const [afterSalesResolutionForm] = Form.useForm<AfterSalesResolutionFormValues>()

  const afterSalesSharingQuery = useQuery({
    queryKey: ['admin-worker-platform-after-sales-sharing', afterSalesOrder?.workOrderId],
    queryFn: () => fetchAdminWorkOrderSharing(Number(afterSalesOrder?.workOrderId)),
    enabled: Boolean(afterSalesOrder?.sharing?.enabled),
  })
  const afterSalesCasesQuery = useQuery({
    queryKey: ['admin-worker-platform-after-sales-cases', afterSalesPage, afterSalesPageSize],
    queryFn: () =>
      fetchAdminAfterSalesCases({ page: afterSalesPage, pageSize: afterSalesPageSize }),
  })

  useImperativeHandle(ref, () => ({
    openCreateModal: (row: WorkOrder) => {
      setAfterSalesOrder(row)
      setAfterSalesFiles([])
      afterSalesCreateForm.setFieldsValue({
        shareId: undefined,
        problemType: 'fake_evidence',
        complaintNote: '',
      })
    },
  }))

  async function runAction<T>(
    action: () => Promise<T>,
    successMessage: string | ((result: T) => string),
  ) {
    try {
      const result = await action()
      message.success(
        typeof successMessage === 'function' ? successMessage(result) : successMessage,
      )
      await queryClient.invalidateQueries({
        queryKey: ['admin-worker-platform-after-sales-cases'],
      })
      return true
    } catch (error) {
      message.error(error instanceof Error ? error.message : '操作失败')
      return false
    }
  }

  async function submitAfterSalesCreate(values: AfterSalesCreateFormValues) {
    if (!afterSalesOrder) return
    const succeeded = await runAction(
      () =>
        createAdminAfterSalesCase(afterSalesOrder.workOrderId, {
          shareId: values.shareId || null,
          problemType: values.problemType || 'fake_evidence',
          complaintNote: String(values.complaintNote || '').trim(),
          files: afterSalesFiles,
        }),
      '售后问题单已创建，已通知责任打手说明',
    )
    if (!succeeded) return
    setAfterSalesOrder(null)
    setAfterSalesFiles([])
    afterSalesCreateForm.resetFields()
  }

  function openAfterSalesResolutionModal(item: WorkerAfterSalesCase) {
    setAfterSalesCase(item)
    afterSalesResolutionForm.setFieldsValue({
      action: 'upheld',
      resolutionNote: '',
      recoveryAmount: Number(item.recoveryAmount || 0) / 100,
    })
  }

  async function submitAfterSalesResolution(values: AfterSalesResolutionFormValues) {
    const action = values.action
    if (!afterSalesCase || !action) return
    const succeeded = await runAction(
      () =>
        resolveAdminAfterSalesCase(afterSalesCase.caseId, {
          action,
          resolutionNote: String(values.resolutionNote || '').trim(),
          recoveryAmount: action === 'upheld' ? Number(values.recoveryAmount || 0) : 0,
        }),
      (result) =>
        (result.data?.refundedTotalAmount || 0) > 0
          ? `售后问题单已处置，已退还原追缴 ${formatMoney(result.data.refundedTotalAmount)} 至打手可用余额`
          : '售后问题单已处置',
    )
    if (!succeeded) return
    setAfterSalesCase(null)
    afterSalesResolutionForm.resetFields()
  }

  return (
    <>
      <Card
        title="验收后售后问题单"
        extra={
          <Button
            icon={<ReloadOutlined />}
            loading={afterSalesCasesQuery.isFetching}
            onClick={() => afterSalesCasesQuery.refetch()}
          >
            刷新
          </Button>
        }
        bordered={false}
      >
        <Table<WorkerAfterSalesCase>
          rowKey="caseId"
          loading={afterSalesCasesQuery.isLoading}
          dataSource={afterSalesCasesQuery.data?.data.items || []}
          pagination={buildAdminTablePagination({
            current: afterSalesCasesQuery.data?.data.pagination?.page || afterSalesPage,
            pageSize: afterSalesCasesQuery.data?.data.pagination?.pageSize || afterSalesPageSize,
            total: afterSalesCasesQuery.data?.data.pagination?.total || 0,
            onChange: (nextPage, nextPageSize) => {
              setAfterSalesPage(nextPage)
              setAfterSalesPageSize(nextPageSize)
            },
          })}
          scroll={{ x: 1160 }}
          columns={[
            {
              title: '售后单',
              width: 190,
              render: (_, item) => (
                <div className="cell-stack">
                  <Typography.Text strong>{item.caseNo}</Typography.Text>
                  <Typography.Text type="secondary">{item.workOrderNo || '-'}</Typography.Text>
                  <Typography.Text type="secondary" style={{ fontSize: 12 }}>
                    {formatAdminDateTime(item.createdAt)}
                  </Typography.Text>
                </div>
              ),
            },
            {
              title: '责任打手',
              width: 150,
              render: (_, item) => (
                <div className="cell-stack">
                  <Typography.Text>{item.workerName || `打手#${item.workerId}`}</Typography.Text>
                  {item.shareQuantity ? (
                    <Tag color="purple">拼单 {item.shareQuantity} 份</Tag>
                  ) : null}
                </div>
              ),
            },
            {
              title: '投诉与证据',
              width: 260,
              render: (_, item) => (
                <div className="cell-stack">
                  <Tag color="red">{formatAfterSalesProblemType(item.problemType)}</Tag>
                  <Typography.Text ellipsis={{ tooltip: item.complaintNote }}>
                    {item.complaintNote || '-'}
                  </Typography.Text>
                  {item.complaintFiles.length > 0 ? (
                    <ImagePreviewList files={item.complaintFiles} size={36} maxVisible={3} />
                  ) : null}
                  {getAfterSalesSnapshotFiles(item).length > 0 ? (
                    <Space size={6} align="center">
                      <Typography.Text type="secondary" style={{ fontSize: 12 }}>
                        固化验收图
                      </Typography.Text>
                      <ImagePreviewList
                        files={getAfterSalesSnapshotFiles(item)}
                        size={36}
                        maxVisible={3}
                      />
                    </Space>
                  ) : null}
                </div>
              ),
            },
            {
              title: '打手说明',
              width: 250,
              render: (_, item) => (
                <div className="cell-stack">
                  <Typography.Text ellipsis={{ tooltip: item.workerResponse }}>
                    {item.workerResponse || '暂未提交'}
                  </Typography.Text>
                  {item.workerResponseFiles.length > 0 ? (
                    <ImagePreviewList files={item.workerResponseFiles} size={36} maxVisible={3} />
                  ) : null}
                  {item.respondedAt ? (
                    <Typography.Text type="secondary" style={{ fontSize: 12 }}>
                      {formatAdminDateTime(item.respondedAt)}
                    </Typography.Text>
                  ) : null}
                </div>
              ),
            },
            {
              title: '处置与追缴',
              width: 240,
              render: (_, item) => (
                <div className="cell-stack">
                  <Tag color={resolveAfterSalesStatusColor(item.status)}>
                    {formatAfterSalesStatus(item.status)}
                  </Tag>
                  {item.resolutionAction ? (
                    <Typography.Text type="secondary" ellipsis={{ tooltip: item.resolutionNote }}>
                      {formatAfterSalesResolution(item.resolutionAction)} ·{' '}
                      {item.resolutionNote || '-'}
                    </Typography.Text>
                  ) : null}
                  {item.resolutionAction === 'upheld' ? (
                    <Typography.Text type={item.debtAmount > 0 ? 'danger' : undefined}>
                      追缴 {formatMoney(item.recoveryAmount)}，待还 {formatMoney(item.debtAmount)}
                    </Typography.Text>
                  ) : null}
                  {item.refundedAmount > 0 ? (
                    <Typography.Text type="success">
                      已退还 {formatMoney(item.refundedAmount)}
                    </Typography.Text>
                  ) : null}
                </div>
              ),
            },
            {
              title: '操作',
              width: 120,
              render: (_, item) =>
                ['awaiting_worker_response', 'under_review'].includes(item.status) ? (
                  <Button
                    type="primary"
                    size="small"
                    onClick={() => openAfterSalesResolutionModal(item)}
                  >
                    处置
                  </Button>
                ) : (
                  <Typography.Text type="secondary">已完成</Typography.Text>
                ),
            },
          ]}
        />
      </Card>

      <Modal
        title={`发起验收后售后 · ${afterSalesOrder ? String(afterSalesOrder.platformOrderId || '').trim() || '-' : ''}`}
        open={Boolean(afterSalesOrder)}
        onCancel={() => {
          setAfterSalesOrder(null)
          setAfterSalesFiles([])
          afterSalesCreateForm.resetFields()
        }}
        onOk={() => afterSalesCreateForm.submit()}
        destroyOnHidden
      >
        {afterSalesOrder ? (
          <Form form={afterSalesCreateForm} layout="vertical" onFinish={submitAfterSalesCreate}>
            <Alert
              showIcon
              type="warning"
              message="售后不会回退已验收工单；原验收资料会在创建时固化。"
              style={{ marginBottom: 16 }}
            />
            {(afterSalesSharingQuery.data?.data.shares || []).some(
              (share) => share.status === 'accepted',
            ) ? (
              <Form.Item
                label="责任拼单份额"
                name="shareId"
                rules={[{ required: true, message: '请选择责任打手的已验收份额' }]}
              >
                <Select
                  loading={afterSalesSharingQuery.isLoading}
                  placeholder="请选择责任拼单份额"
                  options={(afterSalesSharingQuery.data?.data.shares || [])
                    .filter((share) => share.status === 'accepted')
                    .map((share) => ({
                      value: share.shareId,
                      label: `${share.worker?.displayName || share.worker?.username || `打手#${share.workerId}`} · ${share.quantity} 份`,
                    }))}
                />
              </Form.Item>
            ) : null}
            <Form.Item label="问题类型" name="problemType" rules={[{ required: true }]}>
              <Select
                options={[
                  { value: 'fake_evidence', label: '疑似 P 图 / 伪造验收' },
                  { value: 'result_not_met', label: '实际结果未达标' },
                  { value: 'other', label: '其他售后问题' },
                ]}
              />
            </Form.Item>
            <Form.Item
              label="用户投诉说明"
              name="complaintNote"
              rules={[{ required: true, message: '请填写用户投诉说明' }]}
            >
              <Input.TextArea rows={4} placeholder="记录用户反馈、核查结论及需打手说明的事项" />
            </Form.Item>
            <Form.Item label="用户证据图片">
              <ImageUpload
                scene="collect-material"
                scope="admin"
                value={afterSalesFiles}
                onChange={setAfterSalesFiles}
                maxCount={10}
                showPasteHint
              />
            </Form.Item>
          </Form>
        ) : null}
      </Modal>

      <Modal
        title={`处置售后问题单 · ${afterSalesCase?.caseNo || ''}`}
        open={Boolean(afterSalesCase)}
        onCancel={() => {
          setAfterSalesCase(null)
          afterSalesResolutionForm.resetFields()
        }}
        onOk={() => afterSalesResolutionForm.submit()}
        destroyOnHidden
      >
        {afterSalesCase ? (
          <Form
            form={afterSalesResolutionForm}
            layout="vertical"
            onFinish={submitAfterSalesResolution}
          >
            <Form.Item
              label="处置结论"
              name="action"
              rules={[{ required: true, message: '请选择处置结论' }]}
            >
              <Select
                options={[
                  { value: 'upheld', label: '问题成立，执行追缴' },
                  { value: 'remedied', label: '已补救完成，不追缴' },
                  { value: 'not_upheld', label: '问题不成立，关闭售后' },
                ]}
              />
            </Form.Item>
            <Form.Item
              noStyle
              shouldUpdate={(previous, current) => previous.action !== current.action}
            >
              {({ getFieldValue }) =>
                getFieldValue('action') === 'upheld' ? (
                  <Form.Item
                    label="追缴金额"
                    name="recoveryAmount"
                    rules={[{ required: true, message: '请输入追缴金额' }]}
                    extra="系统依次扣减该责任打手的本单待解冻金额、可用余额；不足部分转为欠款，并从后续验收报酬自动抵扣。"
                  >
                    <InputNumber min={0} precision={2} addonAfter="元" className="full-width" />
                  </Form.Item>
                ) : (
                  <Typography.Paragraph type="secondary" style={{ marginBottom: 16 }}>
                    选择补救完成或问题不成立时，系统自动将该工单同一责任打手此前已追缴且未退还的金额退还至其可用余额。
                  </Typography.Paragraph>
                )
              }
            </Form.Item>
            <Form.Item
              label="处置备注"
              name="resolutionNote"
              rules={[{ required: true, message: '请填写处置备注' }]}
            >
              <Input.TextArea rows={4} />
            </Form.Item>
          </Form>
        ) : null}
      </Modal>
    </>
  )
})

function formatAfterSalesProblemType(value: string): string {
  if (value === 'fake_evidence') return '疑似 P 图 / 伪造验收'
  if (value === 'result_not_met') return '实际结果未达标'
  return '其他售后问题'
}

function formatAfterSalesStatus(value: string): string {
  if (value === 'awaiting_worker_response') return '待打手说明'
  if (value === 'under_review') return '客服处理中'
  if (value === 'recovery_pending') return '追缴中'
  return '已关闭'
}

function resolveAfterSalesStatusColor(value: string): string {
  if (value === 'awaiting_worker_response') return 'orange'
  if (value === 'under_review') return 'blue'
  if (value === 'recovery_pending') return 'red'
  return 'green'
}

function formatAfterSalesResolution(value: string): string {
  if (value === 'upheld') return '问题成立'
  if (value === 'remedied') return '补救完成'
  if (value === 'not_upheld') return '问题不成立'
  return value || '-'
}

function getAfterSalesSnapshotFiles(item: WorkerAfterSalesCase): UploadedFile[] {
  const snapshot = asRecord(item.acceptanceSnapshot)
  const acceptance = asRecord(snapshot.acceptance)
  const files = Array.isArray(acceptance.files) ? acceptance.files : []
  const imageUrls = Array.isArray(acceptance.imageUrls) ? acceptance.imageUrls : []
  // 验收资料里同一张图会同时存在于 files 与 imageUrls（历史冗余表示），
  // 必须按图片身份去重，否则固化验收图会把同一张图重复渲染多次。
  return uniqueUploadedFiles(
    [
      ...files.map((value) => asRecord(value)),
      ...imageUrls.map((url) => asRecord({ url: String(url || '') })),
    ]
      .map((file) => {
        const url = String(file.url || '').trim()
        if (!url) return null
        return {
          objectKey: String(file.objectKey || file.object_key || ''),
          url,
          thumbnailUrl: String(file.thumbnailUrl || file.thumbnail_url || url),
          mediumUrl: String(file.mediumUrl || file.medium_url || url),
          filename: String(file.filename || '验收图片'),
          contentType: String(file.contentType || ''),
          size: Number(file.size || 0),
        } satisfies UploadedFile
      })
      .filter((file): file is UploadedFile => file !== null),
  )
}

export default AfterSalesPanel
