"use client"

import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { EmptyState } from "@/components/ui/empty-state"
import { Label } from "@/components/ui/label"
import { Separator } from "@/components/ui/separator"
import { StatusBadge, type StatusBadgeProps } from "@/components/ui/status-badge"
import { Textarea } from "@/components/ui/textarea"
import { getOrderById } from "@/lib/api"
import {
  getDisputeByOrderId,
  submitDispute,
  submitDisputeAppeal,
  submitDisputeResponse,
} from "@/lib/api/disputes"
import { DISPUTE_TO_RESOLVED_MS } from "@/lib/config/demo-timers"
import { notifyInfo } from "@/lib/toast"
import { useAuthStore } from "@/store/auth"
import { AlertTriangle, ArrowLeft, Clock, FileText, Upload, X } from "lucide-react"
import Image from "next/image"
import Link from "next/link"
import { useRouter, useSearchParams } from "next/navigation"
import {
  type ChangeEvent,
  type Dispatch,
  type SetStateAction,
  use,
  useEffect,
  useRef,
  useState,
} from "react"

const disputeStatusLabels: Record<string, string> = {
  open: "已提交",
  reviewing: "审核中",
  resolved: "已解决",
  appealed: "申诉中",
}

const disputeStatusVariants: Record<string, StatusBadgeProps["status"]> = {
  open: "warning",
  reviewing: "info",
  resolved: "success",
  appealed: "info",
}

function deriveMinimalTimeline<TCreatedAt>(dispute: {
  id: string
  status: string
  createdAt: TCreatedAt
  timeline?: { id: string; content: string; createdAt: TCreatedAt }[]
}) {
  const existing = dispute.timeline
  if (existing?.length) return existing

  const steps = [
    { status: "open", content: "争议已提交" },
    { status: "reviewing", content: "平台审核中" },
    { status: "resolved", content: "争议已解决" },
    { status: "appealed", content: "已发起申诉" },
  ]

  const currentIndex = steps.findIndex((step) => step.status === dispute.status)
  const lastIndex = currentIndex >= 0 ? currentIndex : 0
  return steps.slice(0, lastIndex + 1).map((step) => ({
    id: `${dispute.id}-${step.status}`,
    content: step.content,
    createdAt: dispute.createdAt,
  }))
}

export default function DisputePage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = use(params)
  const router = useRouter()
  const searchParams = useSearchParams()
  const userId = useAuthStore((state) => state.user?.id)

  const [loading, setLoading] = useState(true)
  const [order, setOrder] = useState<Awaited<ReturnType<typeof getOrderById>> | null>(null)
  const [existingDispute, setExistingDispute] = useState<Awaited<
    ReturnType<typeof getDisputeByOrderId>
  > | null>(null)

  const [reason, setReason] = useState("")
  const [files, setFiles] = useState<string[]>([])
  const [responseReason, setResponseReason] = useState("")
  const [responseFiles, setResponseFiles] = useState<string[]>([])
  const [appealReason, setAppealReason] = useState("")

  const fileInputRef = useRef<HTMLInputElement>(null)
  const responseFileInputRef = useRef<HTMLInputElement>(null)
  const filesRef = useRef<string[]>([])
  const responseFilesRef = useRef<string[]>([])

  useEffect(() => {
    let cancelled = false

    const reset = () => {
      setLoading(true)
      setOrder(null)
      setExistingDispute(null)
    }

    const load = async () => {
      reset()

      const [nextOrder, nextDispute] = await Promise.all([
        Promise.resolve(getOrderById(id)),
        Promise.resolve(getDisputeByOrderId(id)),
      ])

      if (cancelled) return
      setOrder(nextOrder ?? null)
      setExistingDispute(nextDispute ?? null)
      setLoading(false)
    }

    void load()

    return () => {
      cancelled = true
    }
  }, [id])

  useEffect(() => {
    filesRef.current = files
  }, [files])

  useEffect(() => {
    responseFilesRef.current = responseFiles
  }, [responseFiles])

  useEffect(
    () => () => {
      filesRef.current.forEach((url) => {
        URL.revokeObjectURL(url)
      })
      responseFilesRef.current.forEach((url) => {
        URL.revokeObjectURL(url)
      })
    },
    [],
  )

  const handleFileSelect = (
    event: ChangeEvent<HTMLInputElement>,
    setter: Dispatch<SetStateAction<string[]>>,
  ) => {
    const selectedFiles = event.target.files
    if (!selectedFiles?.length) return

    setter((prev) => {
      const remaining = 5 - prev.length
      if (remaining <= 0) return prev

      const nextUrls = Array.from(selectedFiles)
        .slice(0, remaining)
        .map((file) => URL.createObjectURL(file))
      return [...prev, ...nextUrls]
    })

    event.target.value = ""
  }

  const removeFile = (
    index: number,
    filesState: string[],
    setter: Dispatch<SetStateAction<string[]>>,
  ) => {
    const removed = filesState[index]
    if (removed) {
      URL.revokeObjectURL(removed)
    }
    setter((prev) => prev.filter((_, currentIndex) => currentIndex !== index))
  }

  const handleSubmit = () => {
    if (!userId || !reason.trim()) return

    void Promise.resolve(
      submitDispute({
        orderId: id,
        reason,
        evidence: files,
      }),
    ).then((result) => {
      if (!result.decision.ok) {
        notifyInfo(result.decision.error.msg)
        return
      }
      router.replace(`/dispute/${id}?submitted=1`)
    })
  }

  const showSubmitted = !loading && searchParams.get("submitted") === "1" && !existingDispute

  if (loading) {
    return (
      <div className="container mx-auto max-w-lg px-4 py-8">
        <EmptyState title="争议加载中" icon={Clock} />
      </div>
    )
  }

  if (!order) {
    return (
      <div className="container mx-auto max-w-lg px-4 py-8">
        <EmptyState title="订单不存在" description="无法找到对应订单。" icon={FileText} />
      </div>
    )
  }

  const isParticipant = Boolean(
    userId && (order.consumerId === userId || order.playerId === userId),
  )
  if (!isParticipant) {
    return (
      <div className="container mx-auto max-w-lg px-4 py-8">
        <EmptyState
          title="无法访问争议页面"
          description="仅该订单参与方可访问争议页面。"
          icon={AlertTriangle}
        />
      </div>
    )
  }

  if (existingDispute) {
    const canRespond =
      isParticipant &&
      !existingDispute.respondentReason &&
      (existingDispute.status === "open" || existingDispute.status === "reviewing")
    const canAppeal =
      isParticipant && existingDispute.status === "resolved" && !existingDispute.appealedAt

    const timeline = deriveMinimalTimeline(existingDispute)

    return (
      <div className="container mx-auto max-w-2xl px-4 py-8 space-y-4">
        <Link
          href={`/order/${id}`}
          className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
        >
          <ArrowLeft className="h-4 w-4" />
          返回订单
        </Link>

        <Card className="border-border/80 shadow-sm">
          <CardHeader>
            <div className="flex items-center justify-between">
              <CardTitle>争议详情</CardTitle>
              <StatusBadge status={disputeStatusVariants[existingDispute.status] ?? "neutral"}>
                {disputeStatusLabels[existingDispute.status]}
              </StatusBadge>
            </div>
          </CardHeader>
          <CardContent className="space-y-5">
            <div className="space-y-2">
              <div className="flex items-center gap-2 text-sm">
                <FileText className="h-4 w-4 text-muted-foreground" />
                <span className="text-muted-foreground">发起人:</span>
                发起方
              </div>
              <div className="flex items-center gap-2 text-sm">
                <Clock className="h-4 w-4 text-muted-foreground" />
                <span className="text-muted-foreground">提交时间:</span>
                {new Date(existingDispute.createdAt).toLocaleString("zh-CN")}
              </div>
            </div>

            <Separator />

            <div className="space-y-2">
              <Label className="text-muted-foreground">发起方举证</Label>
              <p className="text-sm">{existingDispute.reason}</p>
              {existingDispute.evidence.length > 0 && (
                <div className="flex gap-2 flex-wrap">
                  {existingDispute.evidence.map((url) => (
                    <div
                      key={url}
                      className="relative h-20 w-20 overflow-hidden rounded-md border border-border/60 bg-muted/30"
                    >
                      <Image src={url} alt="发起方证据" fill unoptimized className="object-cover" />
                    </div>
                  ))}
                </div>
              )}
            </div>

            <Separator />

            <div className="space-y-2">
              <Label className="text-muted-foreground">对方举证</Label>
              {existingDispute.respondentReason ? (
                <>
                  <p className="text-sm">{existingDispute.respondentReason}</p>
                  {existingDispute.respondentEvidence.length > 0 && (
                    <div className="flex gap-2 flex-wrap">
                      {existingDispute.respondentEvidence.map((url) => (
                        <div
                          key={url}
                          className="relative h-20 w-20 overflow-hidden rounded-md border border-border/60 bg-muted/30"
                        >
                          <Image
                            src={url}
                            alt="对方证据"
                            fill
                            unoptimized
                            className="object-cover"
                          />
                        </div>
                      ))}
                    </div>
                  )}
                </>
              ) : (
                <p className="text-sm text-muted-foreground">对方暂未提交回应材料。</p>
              )}
            </div>

            {canRespond && (
              <>
                <Separator />
                <div className="space-y-3">
                  <Label htmlFor="response-reason">提交回应</Label>
                  <Textarea
                    id="response-reason"
                    value={responseReason}
                    onChange={(event) => setResponseReason(event.target.value)}
                    placeholder="请补充说明你的情况..."
                    rows={3}
                  />
                  <input
                    ref={responseFileInputRef}
                    type="file"
                    accept="image/*"
                    multiple
                    className="hidden"
                    onChange={(event) => handleFileSelect(event, setResponseFiles)}
                  />
                  <Button
                    variant="outline"
                    className="border-border/60"
                    onClick={() => responseFileInputRef.current?.click()}
                  >
                    <Upload className="mr-1 h-4 w-4" />
                    上传回应证据
                  </Button>
                  {responseFiles.length > 0 && (
                    <div className="grid grid-cols-5 gap-2">
                      {responseFiles.map((url, index) => (
                        <div
                          key={url}
                          className="relative h-16 w-16 overflow-hidden rounded-md border border-border/60 bg-muted/30"
                        >
                          <Image
                            src={url}
                            alt={`回应证据 ${index + 1}`}
                            fill
                            unoptimized
                            className="object-cover"
                          />
                          <button
                            type="button"
                            aria-label={`移除回应证据 ${index + 1}`}
                            className="absolute right-0 top-0 rounded-bl bg-background/90 p-0.5"
                            onClick={() => removeFile(index, responseFiles, setResponseFiles)}
                          >
                            <X className="h-3 w-3" />
                          </button>
                        </div>
                      ))}
                    </div>
                  )}
                  <Button
                    onClick={() => {
                      if (!userId) return
                      void Promise.resolve(
                        submitDisputeResponse({
                          disputeId: existingDispute.id,
                          reason: responseReason,
                          evidence: responseFiles,
                        }),
                      ).then((decision) => {
                        if (!decision.ok) {
                          notifyInfo(decision.error.msg)
                        }
                      })
                    }}
                    disabled={!responseReason.trim()}
                  >
                    提交回应
                  </Button>
                </div>
              </>
            )}

            {existingDispute.result && (
              <>
                <Separator />
                <div className="space-y-1">
                  <Label className="text-muted-foreground">仲裁结果</Label>
                  <p className="text-sm font-medium">
                    {existingDispute.result === "full_refund"
                      ? "全额退款"
                      : existingDispute.result === "full_payment"
                        ? "全额支付给打手"
                        : "部分退款"}
                  </p>
                </div>
              </>
            )}

            {canAppeal && (
              <>
                <Separator />
                <div className="space-y-2">
                  <Label htmlFor="appeal-reason">申诉（仅一次）</Label>
                  <Textarea
                    id="appeal-reason"
                    value={appealReason}
                    onChange={(event) => setAppealReason(event.target.value)}
                    placeholder="请说明申诉理由..."
                    rows={3}
                  />
                  <Button
                    variant="outline"
                    className="border-border/60"
                    onClick={() => {
                      if (!userId) return
                      void Promise.resolve(
                        submitDisputeAppeal({
                          disputeId: existingDispute.id,
                          reason: appealReason,
                        }),
                      ).then((decision) => {
                        if (!decision.ok) {
                          notifyInfo(decision.error.msg)
                        }
                      })
                    }}
                    disabled={!appealReason.trim()}
                  >
                    提交申诉
                  </Button>
                </div>
              </>
            )}

            <Separator />

            <div className="space-y-2">
              <Label className="text-muted-foreground">处理时间线</Label>
              <div className="rounded-lg border border-border/60">
                {timeline.map((item) => (
                  <div
                    key={item.id}
                    className="flex items-start justify-between gap-3 border-b border-border/60 px-3 py-2 text-sm last:border-b-0"
                  >
                    <span>{item.content}</span>
                    <span className="text-xs text-muted-foreground shrink-0">
                      {new Date(item.createdAt).toLocaleString("zh-CN")}
                    </span>
                  </div>
                ))}
              </div>
            </div>
          </CardContent>
        </Card>
      </div>
    )
  }

  if (showSubmitted) {
    return (
      <div className="container mx-auto max-w-lg px-4 py-8">
        <EmptyState
          title="争议已提交，请等待平台处理"
          description={`平台将在约 ${Math.floor(DISPUTE_TO_RESOLVED_MS / 1000)} 秒内给出模拟处理结果。`}
          icon={AlertTriangle}
          action={
            <Button variant="outline" className="border-border/60" asChild>
              <Link href={`/order/${id}`}>返回订单详情</Link>
            </Button>
          }
        />
      </div>
    )
  }

  return (
    <div className="container mx-auto max-w-lg px-4 py-8 space-y-4">
      <Link
        href={`/order/${id}`}
        className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
      >
        <ArrowLeft className="h-4 w-4" />
        返回订单
      </Link>

      <Card className="border-border/80 shadow-sm">
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <AlertTriangle className="h-5 w-5 text-warning" />
            发起争议
          </CardTitle>
          <p className="text-sm text-muted-foreground">{order.service.title}</p>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="dispute-reason">争议原因</Label>
            <Textarea
              id="dispute-reason"
              placeholder="请详细描述你遇到的问题..."
              value={reason}
              onChange={(event) => setReason(event.target.value)}
              rows={4}
            />
          </div>

          <div className="space-y-2">
            <Label>上传证据截图</Label>
            <input
              ref={fileInputRef}
              type="file"
              accept="image/*"
              multiple
              className="hidden"
              onChange={(event) => handleFileSelect(event, setFiles)}
            />
            <button
              type="button"
              className="w-full rounded-md border-2 border-dashed border-border/60 bg-muted/20 p-6 text-center text-sm text-muted-foreground transition-colors hover:border-primary/60 hover:bg-muted/30 hover:text-foreground disabled:opacity-50"
              onClick={() => fileInputRef.current?.click()}
              disabled={files.length >= 5}
            >
              <div className="flex flex-col items-center gap-2">
                <Upload className="h-5 w-5" />
                <span>点击上传截图（最多5张）</span>
              </div>
            </button>
            {files.length > 0 && (
              <div className="grid grid-cols-5 gap-2">
                {files.map((fileUrl, index) => (
                  <div
                    key={fileUrl}
                    className="relative h-16 w-16 overflow-hidden rounded-md border border-border/60 bg-muted/30"
                  >
                    <Image
                      src={fileUrl}
                      alt={`证据截图 ${index + 1}`}
                      fill
                      unoptimized
                      className="object-cover"
                    />
                    <button
                      type="button"
                      aria-label={`移除证据截图 ${index + 1}`}
                      className="absolute right-0 top-0 rounded-bl bg-background/90 p-0.5"
                      onClick={() => removeFile(index, files, setFiles)}
                    >
                      <X className="h-3 w-3" />
                    </button>
                  </div>
                ))}
              </div>
            )}
            <div className="text-xs text-muted-foreground">最多5张</div>
          </div>

          <div className="space-y-1 rounded-lg border border-border/60 bg-muted/20 p-3 text-xs text-muted-foreground">
            <p>· 提交争议后，订单资金将继续托管</p>
            <p>· 聊天记录将作为证据保留</p>
            <p>· 平台将在约 {Math.floor(DISPUTE_TO_RESOLVED_MS / 1000)} 秒内完成模拟审核</p>
            <p>· 对仲裁结果不满可申诉一次</p>
          </div>

          <Button className="w-full" disabled={!reason.trim() || !userId} onClick={handleSubmit}>
            提交争议
          </Button>
        </CardContent>
      </Card>
    </div>
  )
}
