import { BookOpenText, Bot, Check, RefreshCcw, RotateCcw, Save, Trash2 } from 'lucide-react'
import { startTransition, useCallback, useEffect, useMemo, useState } from 'react'
import { toast } from 'sonner'

import { FormField } from '@/components/form-field'
import { MediaUrlControls } from '@/components/media-url-controls'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Select } from '@/components/ui/select'
import { Skeleton } from '@/components/ui/skeleton'
import { Textarea } from '@/components/ui/textarea'
import { adminApi, ApiError } from '@/lib/api'
import {
  csvToList,
  formatDateTime,
  formatReviewStatus,
  formatReviewType,
  reviewTagsToList,
} from '@/lib/admin-format'
import type { CreateReviewPayload, ReviewRecord, UpdateReviewPayload } from '@/lib/types'

type ReviewFormState = {
  title: string
  reviewType: string
  rating: string
  reviewDate: string
  status: string
  description: string
  tags: string
  cover: string
  linkUrl: string
}

type ReviewDescriptionPolishState = {
  originalDescription: string
  polishedDescription: string
}

const defaultReviewForm: ReviewFormState = {
  title: '',
  reviewType: 'book',
  rating: '4',
  reviewDate: '',
  status: 'published',
  description: '',
  tags: '',
  cover: '',
  linkUrl: '',
}

function toFormState(review: ReviewRecord): ReviewFormState {
  return {
    title: review.title ?? '',
    reviewType: review.review_type ?? 'book',
    rating: String(review.rating ?? 4),
    reviewDate: review.review_date ?? '',
    status: review.status ?? 'published',
    description: review.description ?? '',
    tags: reviewTagsToList(review.tags).join(', '),
    cover: review.cover ?? '',
    linkUrl: review.link_url ?? '',
  }
}

function toCreatePayload(form: ReviewFormState): CreateReviewPayload {
  return {
    title: form.title.trim(),
    review_type: form.reviewType,
    rating: Number(form.rating),
    review_date: form.reviewDate,
    status: form.status,
    description: form.description.trim(),
    tags: csvToList(form.tags),
    cover: form.cover.trim(),
    link_url: form.linkUrl.trim() || null,
  }
}

function toUpdatePayload(form: ReviewFormState): UpdateReviewPayload {
  return {
    title: form.title.trim(),
    review_type: form.reviewType,
    rating: Number(form.rating),
    review_date: form.reviewDate,
    status: form.status,
    description: form.description.trim(),
    tags: csvToList(form.tags),
    cover: form.cover.trim(),
    link_url: form.linkUrl.trim() || null,
  }
}

export function ReviewsPage() {
  const [reviews, setReviews] = useState<ReviewRecord[]>([])
  const [selectedId, setSelectedId] = useState<number | null>(null)
  const [form, setForm] = useState<ReviewFormState>(defaultReviewForm)
  const [loading, setLoading] = useState(true)
  const [refreshing, setRefreshing] = useState(false)
  const [saving, setSaving] = useState(false)
  const [deleting, setDeleting] = useState(false)
  const [polishingDescription, setPolishingDescription] = useState(false)
  const [descriptionPolish, setDescriptionPolish] = useState<ReviewDescriptionPolishState | null>(
    null,
  )
  const [searchTerm, setSearchTerm] = useState('')
  const [statusFilter, setStatusFilter] = useState('all')

  const loadReviews = useCallback(async (showToast = false) => {
    try {
      if (showToast) {
        setRefreshing(true)
      }

      const next = await adminApi.listReviews()
      startTransition(() => {
        setReviews(next)
      })

      if (showToast) {
        toast.success('评测列表已刷新。')
      }
    } catch (error) {
      if (error instanceof ApiError && error.status === 401) {
        return
      }
      toast.error(error instanceof ApiError ? error.message : '无法加载评测列表。')
    } finally {
      setLoading(false)
      setRefreshing(false)
    }
  }, [])

  useEffect(() => {
    void loadReviews(false)
  }, [loadReviews])

  const filteredReviews = useMemo(() => {
    return reviews.filter((review) => {
      const matchesSearch =
        !searchTerm ||
        [
          review.title ?? '',
          review.review_type ?? '',
          review.description ?? '',
          review.tags ?? '',
          review.status ?? '',
        ]
          .join('\n')
          .toLowerCase()
          .includes(searchTerm.toLowerCase())

      const matchesStatus =
        statusFilter === 'all' || (review.status ?? 'published') === statusFilter

      return matchesSearch && matchesStatus
    })
  }, [reviews, searchTerm, statusFilter])

  const selectedReview = useMemo(
    () => reviews.find((review) => review.id === selectedId) ?? null,
    [reviews, selectedId],
  )

  const requestDescriptionPolish = useCallback(async () => {
    if (!form.description.trim()) {
      toast.error('请先写一点点评内容，再让 AI 帮你润色。')
      return
    }

    try {
      setPolishingDescription(true)
      const result = await adminApi.polishReviewDescription({
        title: form.title.trim() || '未命名评测',
        reviewType: form.reviewType,
        rating: Number(form.rating) || 0,
        reviewDate: form.reviewDate || null,
        status: form.status,
        tags: csvToList(form.tags),
        description: form.description,
      })
      const polishedDescription =
        typeof result.polished_description === 'string' ? result.polished_description : ''

      if (!polishedDescription.trim()) {
        throw new Error('AI 润色返回为空。')
      }

      startTransition(() => {
        setDescriptionPolish({
          originalDescription: form.description,
          polishedDescription,
        })
      })

      if (polishedDescription.trim() === form.description.trim()) {
        toast.success('AI 已检查这段点评，当前文案已经比较完整。')
      } else {
        toast.success('AI 已生成一版更顺的点评文案，可以先对比再决定是否采用。')
      }
    } catch (error) {
      toast.error(
        error instanceof ApiError
          ? error.message
          : error instanceof Error
            ? error.message
            : 'AI 润色点评失败。',
      )
    } finally {
      setPolishingDescription(false)
    }
  }, [form])

  return (
    <div className="space-y-6">
      <div className="flex flex-col gap-4 xl:flex-row xl:items-end xl:justify-between">
        <div className="space-y-3">
          <Badge variant="secondary">评测</Badge>
          <div>
            <h2 className="text-3xl font-semibold tracking-tight">评测内容库</h2>
            <p className="mt-2 max-w-3xl text-sm leading-7 text-muted-foreground">
              管理前台评测页依赖的评测目录，包括评分、媒介类型、封面和发布状态。
            </p>
          </div>
        </div>

        <div className="flex flex-wrap items-center gap-3">
          <Button
            variant="outline"
            onClick={() => {
              setSelectedId(null)
              setForm(defaultReviewForm)
              setDescriptionPolish(null)
            }}
          >
            新建评测
          </Button>
          <Button variant="secondary" onClick={() => void loadReviews(true)} disabled={refreshing}>
            <RefreshCcw className="h-4 w-4" />
            {refreshing ? '刷新中...' : '刷新'}
          </Button>
        </div>
      </div>

      <div className="grid gap-6 xl:grid-cols-[0.92fr_1.08fr]">
        <Card>
          <CardHeader>
            <CardTitle>评测列表</CardTitle>
            <CardDescription>
              选择已有评测进行编辑，或者在右侧直接创建新条目。
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="grid gap-3 lg:grid-cols-[1.2fr_0.6fr]">
              <Input
                placeholder="按标题、媒介、简介、标签或状态搜索"
                value={searchTerm}
                onChange={(event) => setSearchTerm(event.target.value)}
              />
              <Select
                value={statusFilter}
                onChange={(event) => setStatusFilter(event.target.value)}
              >
                <option value="all">全部状态</option>
                <option value="published">已发布</option>
                <option value="draft">草稿</option>
                <option value="archived">已归档</option>
              </Select>
            </div>

            {loading ? (
              <Skeleton className="h-[620px] rounded-3xl" />
            ) : (
              <div className="space-y-3">
                {filteredReviews.map((review) => (
                  <button
                    key={review.id}
                    type="button"
                    data-testid={`review-item-${review.id}`}
                    onClick={() => {
                      setSelectedId(review.id)
                      setForm(toFormState(review))
                      setDescriptionPolish(null)
                    }}
                    className={`w-full rounded-3xl border px-4 py-4 text-left transition ${
                      selectedId === review.id
                        ? 'border-primary/30 bg-primary/10 shadow-[0_12px_30px_rgba(37,99,235,0.12)]'
                        : 'border-border/70 bg-background/60 hover:border-border'
                    }`}
                  >
                    <div className="flex items-start justify-between gap-3">
                      <div className="min-w-0 space-y-1">
                        <div className="flex flex-wrap items-center gap-2">
                          <span className="font-medium">{review.title ?? '未命名评测'}</span>
                          <Badge variant="outline">{formatReviewType(review.review_type)}</Badge>
                        </div>
                        <p className="line-clamp-2 text-sm text-muted-foreground">
                          {review.description ?? '暂无简介。'}
                        </p>
                        <p className="text-xs text-muted-foreground">
                          {reviewTagsToList(review.tags).join(', ') || '暂无标签'}
                        </p>
                      </div>
                      <div className="text-right">
                        <div className="text-xl font-semibold">{review.rating ?? 0}/5</div>
                        <p className="mt-1 text-xs uppercase tracking-[0.18em] text-muted-foreground">
                          {formatReviewStatus(review.status)}
                        </p>
                        <p className="mt-2 text-xs text-muted-foreground">
                          {formatDateTime(review.created_at)}
                        </p>
                      </div>
                    </div>
                  </button>
                ))}

                {!filteredReviews.length ? (
                  <div className="flex flex-col items-center gap-3 rounded-3xl border border-dashed border-border/70 px-6 py-14 text-center text-muted-foreground">
                    <BookOpenText className="h-8 w-8" />
                    <p>当前筛选条件下没有匹配的评测。</p>
                  </div>
                ) : null}
              </div>
            )}
          </CardContent>
        </Card>

        <Card>
          <CardHeader className="flex flex-col gap-4 xl:flex-row xl:items-start xl:justify-between">
            <div>
              <CardTitle>{selectedReview ? '编辑评测' : '新建评测'}</CardTitle>
              <CardDescription>
                维护前台评测页直接读取的展示字段。
              </CardDescription>
            </div>
            <div className="flex flex-wrap items-center gap-3">
              <Button
                data-testid="review-save"
                onClick={async () => {
                  if (!form.title.trim()) {
                    toast.error('标题不能为空。')
                    return
                  }

                  if (!form.reviewDate) {
                    toast.error('评测日期不能为空。')
                    return
                  }

                  try {
                    setSaving(true)
                    if (selectedReview) {
                      const updated = await adminApi.updateReview(
                        selectedReview.id,
                        toUpdatePayload(form),
                      )
                      startTransition(() => {
                        setSelectedId(updated.id)
                        setForm(toFormState(updated))
                        setDescriptionPolish(null)
                      })
                      toast.success('评测已更新。')
                    } else {
                      const created = await adminApi.createReview(toCreatePayload(form))
                      startTransition(() => {
                        setSelectedId(created.id)
                        setForm(toFormState(created))
                        setDescriptionPolish(null)
                      })
                      toast.success('评测已创建。')
                    }
                    await loadReviews(false)
                  } catch (error) {
                    toast.error(error instanceof ApiError ? error.message : '无法保存评测。')
                  } finally {
                    setSaving(false)
                  }
                }}
                disabled={saving}
              >
                <Save className="h-4 w-4" />
                {saving ? '保存中...' : selectedReview ? '保存修改' : '创建评测'}
              </Button>
              {selectedReview ? (
                <Button
                  variant="danger"
                  data-testid="review-delete"
                  disabled={deleting}
                  onClick={async () => {
                    if (!window.confirm('确定删除这条评测吗？')) {
                      return
                    }

                    try {
                      setDeleting(true)
                      await adminApi.deleteReview(selectedReview.id)
                      toast.success('评测已删除。')
                      setSelectedId(null)
                      setForm(defaultReviewForm)
                      setDescriptionPolish(null)
                      await loadReviews(false)
                    } catch (error) {
                      toast.error(error instanceof ApiError ? error.message : '无法删除评测。')
                    } finally {
                      setDeleting(false)
                    }
                  }}
                >
                  <Trash2 className="h-4 w-4" />
                  {deleting ? '删除中...' : '删除'}
                </Button>
              ) : null}
            </div>
          </CardHeader>
          <CardContent className="space-y-5">
            {selectedReview ? (
              <div className="rounded-3xl border border-border/70 bg-background/60 p-5">
                <p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">
                  当前记录
                </p>
                <p className="mt-2 text-sm text-muted-foreground">
                  创建于 {formatDateTime(selectedReview.created_at)}
                </p>
              </div>
            ) : null}

            <div className="grid gap-5 lg:grid-cols-2">
              <FormField label="标题">
                <Input
                  data-testid="review-title"
                  value={form.title}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, title: event.target.value }))
                  }
                />
              </FormField>
              <FormField label="评测类型">
                <Select
                  value={form.reviewType}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, reviewType: event.target.value }))
                  }
                >
                  <option value="book">图书</option>
                  <option value="movie">电影</option>
                  <option value="game">游戏</option>
                  <option value="anime">动画</option>
                  <option value="music">音乐</option>
                </Select>
              </FormField>
              <FormField label="评分">
                <Input
                  type="number"
                  min="1"
                  max="5"
                  step="1"
                  value={form.rating}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, rating: event.target.value }))
                  }
                />
              </FormField>
              <FormField label="评测日期">
                <Input
                  data-testid="review-date"
                  type="date"
                  value={form.reviewDate}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, reviewDate: event.target.value }))
                  }
                />
              </FormField>
              <FormField label="状态">
                <Select
                  value={form.status}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, status: event.target.value }))
                  }
                >
                  <option value="published">已发布</option>
                  <option value="draft">草稿</option>
                  <option value="archived">已归档</option>
                </Select>
              </FormField>
              <FormField label="封面 URL" hint="可直接填外链，也可以上传图片到 R2。">
                <div className="space-y-3">
                  <Input
                    value={form.cover}
                    onChange={(event) =>
                      setForm((current) => ({ ...current, cover: event.target.value }))
                    }
                  />
                  <MediaUrlControls
                    value={form.cover}
                    onChange={(cover) => setForm((current) => ({ ...current, cover }))}
                    prefix="review-covers/"
                    contextLabel="评测封面上传"
                    mode="cover"
                    remoteTitle={form.title || '评测封面'}
                    dataTestIdPrefix="review-cover"
                  />

                  {form.cover ? (
                    <div className="overflow-hidden rounded-[1.4rem] border border-border/70 bg-background/70">
                      <img
                        src={form.cover}
                        alt={form.title || '评测封面预览'}
                        className="h-48 w-full object-cover"
                      />
                    </div>
                  ) : null}
                </div>
              </FormField>
              <FormField label="跳转链接" hint="可填写站内路径或完整 URL。">
                <Input
                  type="url"
                  value={form.linkUrl}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, linkUrl: event.target.value }))
                  }
                />
              </FormField>
              <div className="lg:col-span-2">
                <FormField label="标签" hint="多个标签请用英文逗号分隔。">
                  <Input
                    value={form.tags}
                    onChange={(event) =>
                      setForm((current) => ({ ...current, tags: event.target.value }))
                    }
                  />
                </FormField>
              </div>
              <div className="lg:col-span-2">
                <FormField
                  label="简介 / 点评"
                  hint="可以先写你的原始观感，再用 AI 帮你把这段点评润得更顺。"
                >
                  <div className="space-y-3">
                    <div className="flex flex-col gap-3 rounded-[1.5rem] border border-border/70 bg-background/65 px-4 py-4 lg:flex-row lg:items-center lg:justify-between">
                      <p className="text-sm leading-6 text-muted-foreground">
                        AI 会结合当前标题、类型、评分、状态和标签，只润色这段点评文案，不会自动保存。
                      </p>
                      <div className="flex flex-wrap items-center gap-2">
                        <Button
                          size="sm"
                          variant="outline"
                          data-testid="review-ai-polish"
                          onClick={() => void requestDescriptionPolish()}
                          disabled={polishingDescription}
                        >
                          <Bot className="h-4 w-4" />
                          {polishingDescription ? '润色中...' : 'AI 润色点评'}
                        </Button>
                        {descriptionPolish ? (
                          <Button
                            size="sm"
                            variant="ghost"
                            onClick={() => setDescriptionPolish(null)}
                          >
                            <RotateCcw className="h-4 w-4" />
                            收起对比
                          </Button>
                        ) : null}
                      </div>
                    </div>

                    <Textarea
                      data-testid="review-description"
                      value={form.description}
                      onChange={(event) => {
                        const nextDescription = event.target.value
                        setForm((current) => ({ ...current, description: nextDescription }))
                        setDescriptionPolish((current) =>
                          current && current.originalDescription === nextDescription ? current : null,
                        )
                      }}
                    />

                    {descriptionPolish ? (
                      <div className="overflow-hidden rounded-[1.8rem] border border-border/70 bg-background/80">
                        <div className="flex flex-col gap-3 border-b border-border/70 px-5 py-4 lg:flex-row lg:items-center lg:justify-between">
                          <div>
                            <p className="text-base font-semibold">AI 点评润色对比</p>
                            <p className="mt-1 text-sm text-muted-foreground">
                              左边保留当前文案，右边是 AI 建议，你可以直接采用或保留原文。
                            </p>
                          </div>
                          <div className="flex flex-wrap items-center gap-2">
                            <Button
                              size="sm"
                              data-testid="review-ai-adopt"
                              onClick={() => {
                                setForm((current) => ({
                                  ...current,
                                  description: descriptionPolish.polishedDescription,
                                }))
                                setDescriptionPolish(null)
                                toast.success('AI 润色点评已回填到评测简介。')
                              }}
                            >
                              <Check className="h-4 w-4" />
                              采用润色结果
                            </Button>
                            <Button
                              size="sm"
                              variant="outline"
                              onClick={() => void requestDescriptionPolish()}
                              disabled={polishingDescription}
                            >
                              <Bot className="h-4 w-4" />
                              重新润色
                            </Button>
                            <Button
                              size="sm"
                              variant="ghost"
                              onClick={() => setDescriptionPolish(null)}
                            >
                              保留原文
                            </Button>
                          </div>
                        </div>

                        <div className="grid gap-4 p-5 xl:grid-cols-2">
                          <div className="rounded-[1.4rem] border border-border/70 bg-muted/20 p-4">
                            <p className="text-[11px] uppercase tracking-[0.22em] text-muted-foreground">
                              当前点评
                            </p>
                            <p className="mt-3 whitespace-pre-wrap break-words text-sm leading-7">
                              {descriptionPolish.originalDescription.trim() || '未填写'}
                            </p>
                          </div>
                          <div className="rounded-[1.4rem] border border-emerald-500/30 bg-emerald-500/5 p-4">
                            <p className="text-[11px] uppercase tracking-[0.22em] text-muted-foreground">
                              AI 建议
                            </p>
                            <p className="mt-3 whitespace-pre-wrap break-words text-sm leading-7">
                              {descriptionPolish.polishedDescription.trim() || '未填写'}
                            </p>
                          </div>
                        </div>
                      </div>
                    ) : null}
                  </div>
                </FormField>
              </div>
            </div>
          </CardContent>
        </Card>
      </div>
    </div>
  )
}
