import { Bot, CheckCheck, RefreshCcw, WandSparkles } from 'lucide-react'
import { startTransition, useEffect, useMemo, useState } from 'react'
import { toast } from 'sonner'

import {
  configureMonaco,
  editorTheme,
  sharedOptions,
} from '@/components/markdown-workbench'
import { LazyDiffEditor } from '@/components/lazy-monaco'
import { MarkdownPreview } from '@/components/markdown-preview'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { adminApi, ApiError } from '@/lib/api'
import { computeDiffHunks, applySelectedDiffHunks } from '@/lib/markdown-merge'
import {
  loadDraftWindowSnapshot,
  savePolishWindowResult,
  type DraftWindowSnapshot,
} from '@/lib/post-draft-window'

type PolishTarget = 'editor' | 'create'

function getDraftKey() {
  if (typeof window === 'undefined') {
    return null
  }

  return new URLSearchParams(window.location.search).get('draftKey')
}

function getTarget(): PolishTarget {
  if (typeof window === 'undefined') {
    return 'editor'
  }

  const value = new URLSearchParams(window.location.search).get('target')
  return value === 'create' ? 'create' : 'editor'
}

function buildApplyMessage(draftKey: string, markdown: string, target: PolishTarget) {
  return {
    type: 'termi-admin-post-polish-apply',
    draftKey,
    markdown,
    target,
  }
}

export function PostPolishPage() {
  const draftKey = getDraftKey()
  const target = getTarget()
  const [snapshot, setSnapshot] = useState<DraftWindowSnapshot | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [polishing, setPolishing] = useState(false)
  const [polishedMarkdown, setPolishedMarkdown] = useState('')
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set())

  useEffect(() => {
    const draft = loadDraftWindowSnapshot(draftKey)
    if (!draft) {
      setError('没有找到要润色的草稿快照，请从文章编辑页重新打开 AI 润色窗口。')
    } else {
      startTransition(() => {
        setSnapshot(draft)
      })
    }
    setLoading(false)
  }, [draftKey])

  const originalMarkdown = snapshot?.markdown ?? ''
  const hunks = useMemo(
    () => (polishedMarkdown ? computeDiffHunks(originalMarkdown, polishedMarkdown) : []),
    [originalMarkdown, polishedMarkdown],
  )
  const mergedMarkdown = useMemo(
    () => applySelectedDiffHunks(originalMarkdown, hunks, selectedIds),
    [hunks, originalMarkdown, selectedIds],
  )

  const applyAll = () => {
    setSelectedIds(new Set(hunks.map((hunk) => hunk.id)))
  }

  const keepOriginal = () => {
    setSelectedIds(new Set())
  }

  const applyToParent = () => {
    if (!draftKey) {
      toast.error('当前窗口缺少草稿标识，无法回填。')
      return
    }

    const result = savePolishWindowResult(draftKey, mergedMarkdown, target)
    window.opener?.postMessage(buildApplyMessage(draftKey, mergedMarkdown, target), window.location.origin)
    toast.success('已把 AI 润色结果回填到原编辑器。')

    return result
  }

  return (
    <div className="min-h-screen bg-background px-4 py-6 text-foreground lg:px-6">
      <div className="mx-auto max-w-[1560px] space-y-6">
        <div className="flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
          <div className="space-y-3">
            <Badge variant="secondary">AI 润色工作台</Badge>
            <div>
              <h1 className="text-3xl font-semibold tracking-tight">
                {snapshot?.title || 'AI 润色与选择性合并'}
              </h1>
              <p className="mt-2 text-sm leading-6 text-muted-foreground">
                左边保留润色前的原稿，右边是当前选中的合并结果。你可以先生成 AI 润色稿，再按改动块决定要保留哪些内容。
              </p>
            </div>
          </div>

          <div className="flex flex-wrap items-center gap-3">
            <Button
              variant="outline"
              disabled={!snapshot || polishing}
              onClick={async () => {
                if (!snapshot) {
                  return
                }

                try {
                  setPolishing(true)
                  const result = await adminApi.polishPostMarkdown(snapshot.markdown)
                  const nextHunks = computeDiffHunks(snapshot.markdown, result.polished_markdown)
                  startTransition(() => {
                    setPolishedMarkdown(result.polished_markdown)
                    setSelectedIds(new Set(nextHunks.map((hunk) => hunk.id)))
                  })
                  toast.success(`AI 已生成润色稿，共识别 ${nextHunks.length} 个改动块。`)
                } catch (requestError) {
                  toast.error(requestError instanceof ApiError ? requestError.message : 'AI 润色失败。')
                } finally {
                  setPolishing(false)
                }
              }}
            >
              <Bot className="h-4 w-4" />
              {polishing ? '润色中...' : polishedMarkdown ? '重新生成润色稿' : '生成 AI 润色稿'}
            </Button>
            <Button variant="outline" disabled={!hunks.length} onClick={applyAll}>
              <CheckCheck className="h-4 w-4" />
              全部采用
            </Button>
            <Button variant="outline" disabled={!hunks.length} onClick={keepOriginal}>
              <RefreshCcw className="h-4 w-4" />
              全部还原
            </Button>
            <Button disabled={!hunks.length} onClick={applyToParent}>
              <WandSparkles className="h-4 w-4" />
              应用到原编辑器
            </Button>
          </div>
        </div>

        {loading ? (
          <Card>
            <CardContent className="py-12 text-sm text-muted-foreground">正在加载草稿快照...</CardContent>
          </Card>
        ) : error ? (
          <Card>
            <CardHeader>
              <CardTitle>AI 润色窗口加载失败</CardTitle>
              <CardDescription>{error}</CardDescription>
            </CardHeader>
          </Card>
        ) : snapshot ? (
          <div className="grid gap-6 xl:grid-cols-[1.14fr_0.86fr]">
            <div className="space-y-6">
              <Card>
                <CardHeader>
                  <CardTitle>润色前 vs 当前合并结果</CardTitle>
                  <CardDescription>按改动块选择是否采用 AI 润色结果。</CardDescription>
                </CardHeader>
                <CardContent className="space-y-4">
                  <div className="flex flex-wrap items-center gap-3">
                    <Badge variant="secondary">改动块 {hunks.length}</Badge>
                    <Badge variant="success">已采用 {selectedIds.size}</Badge>
                    <Badge variant="outline">目标 {target === 'create' ? '新建草稿' : '现有文章'}</Badge>
                  </div>
                  <div className="overflow-hidden rounded-[28px] border border-slate-800 bg-[#1e1e1e]">
                    <div className="flex items-center justify-between border-b border-slate-800 bg-[#141414] px-4 py-2 text-[11px] uppercase tracking-[0.18em] text-slate-400">
                      <span>润色前原稿</span>
                      <span>当前合并结果</span>
                    </div>
                    <div className="h-[560px]">
                      <LazyDiffEditor
                        height="100%"
                        language="markdown"
                        original={originalMarkdown}
                        modified={mergedMarkdown}
                        originalModelPath={`${snapshot.path}#ai-original`}
                        modifiedModelPath={`${snapshot.path}#ai-merged`}
                        keepCurrentOriginalModel
                        keepCurrentModifiedModel
                        theme={editorTheme}
                        beforeMount={configureMonaco}
                        options={{
                          ...sharedOptions,
                          originalEditable: false,
                          readOnly: true,
                          renderSideBySide: true,
                        }}
                      />
                    </div>
                  </div>
                </CardContent>
              </Card>

              <Card>
                <CardHeader>
                  <CardTitle>当前合并结果预览</CardTitle>
                  <CardDescription>边挑选改动，边查看最终会保存成什么样。</CardDescription>
                </CardHeader>
                <CardContent>
                  <div className="h-[420px] overflow-hidden rounded-[28px] border border-slate-200 bg-white">
                    <MarkdownPreview markdown={mergedMarkdown || originalMarkdown} />
                  </div>
                </CardContent>
              </Card>
            </div>

            <div className="space-y-6">
              <Card>
                <CardHeader>
                  <CardTitle>改动块选择</CardTitle>
                  <CardDescription>
                    每一块都可以单独采用或保留原文，合并结果会立即同步到右侧 diff 和预览。
                  </CardDescription>
                </CardHeader>
                <CardContent className="space-y-3">
                  {!polishedMarkdown ? (
                    <div className="rounded-3xl border border-dashed border-border/70 px-5 py-10 text-sm text-muted-foreground">
                      先点“生成 AI 润色稿”，这里才会出现可选的改动块。
                    </div>
                  ) : hunks.length ? (
                    hunks.map((hunk, index) => {
                      const accepted = selectedIds.has(hunk.id)

                      return (
                        <div
                          key={hunk.id}
                          className={`rounded-3xl border p-4 transition ${
                            accepted
                              ? 'border-emerald-500/30 bg-emerald-500/10'
                              : 'border-border/70 bg-background/60'
                          }`}
                        >
                          <div className="flex items-start justify-between gap-3">
                            <div>
                              <p className="text-sm font-medium">改动块 {index + 1}</p>
                              <p className="mt-1 text-xs leading-5 text-muted-foreground">
                                原文 {hunk.originalStart}-{Math.max(hunk.originalEnd, hunk.originalStart - 1)} 行
                                ，润色稿 {hunk.modifiedStart}-{Math.max(hunk.modifiedEnd, hunk.modifiedStart - 1)} 行
                              </p>
                            </div>
                            <Button
                              size="sm"
                              variant={accepted ? 'default' : 'outline'}
                              onClick={() => {
                                setSelectedIds((current) => {
                                  const next = new Set(current)
                                  if (next.has(hunk.id)) {
                                    next.delete(hunk.id)
                                  } else {
                                    next.add(hunk.id)
                                  }
                                  return next
                                })
                              }}
                            >
                              {accepted ? '已采用' : '采用这块'}
                            </Button>
                          </div>

                          <p className="mt-3 rounded-2xl border border-border/60 bg-background/70 px-3 py-2 text-xs leading-6 text-muted-foreground">
                            {hunk.preview}
                          </p>
                        </div>
                      )
                    })
                  ) : (
                    <div className="rounded-3xl border border-border/70 px-5 py-10 text-sm text-muted-foreground">
                      AI 已返回结果，但没有检测到行级差异。可以直接应用，或者重新生成一次。
                    </div>
                  )}
                </CardContent>
              </Card>
            </div>
          </div>
        ) : null}
      </div>
    </div>
  )
}
