'use client'

import { CheckCircle2, Copy, Download, Eye, FileCode2, History, RefreshCw } from 'lucide-react'

import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from '@/components/ui/accordion'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { ScrollArea } from '@/components/ui/scroll-area'
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
} from '@/components/ui/sheet'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Textarea } from '@/components/ui/textarea'
import {
  buildDisplayPatchResources,
  formatGitDate,
  isSkippedRow,
  resolveBackportProgressText,
  resolveCommitTitle,
  resolveConflictMeta,
  resolveStatusMeta,
  stringifyValue,
} from '@/components/tool-panel/backport/utils'
import {
  classifyPatchLine,
  getLightPatchLineClass,
  type ParsedPatchSummary,
} from '@/lib/patch-utils'
import type {
  BackportCommitRow,
  BackportConfig,
  BackportAttemptSummary,
  BackportOperationResultData,
  BackportPatchPreviewResponse,
  BackportPatchResource,
} from '@/lib/backport-types'
import { cn } from '@/lib/utils'

export type InspectorTab = 'details' | 'history' | 'patch' | 'compare' | 'manual' | 'yaml'

export type PatchLoadState =
  | { status: 'loading'; resource: BackportPatchResource }
  | { status: 'error'; resource: BackportPatchResource; error: string }
  | {
      status: 'ready'
      resource: BackportPatchResource
      response: BackportPatchPreviewResponse
      summary: ParsedPatchSummary
    }

type ReadyPatchLoadState = Extract<PatchLoadState, { status: 'ready' }>

interface InspectorSheetProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  row: BackportCommitRow | null
  config: BackportConfig
  inspectorTab: InspectorTab
  onInspectorTabChange: (tab: InspectorTab) => void
  patchAnchorRefs: React.MutableRefObject<Record<string, HTMLDivElement | null>>
  activePatchKey: string | null
  activePatchPreview: PatchLoadState | null
  compareLeftResource: BackportPatchResource | null
  compareRightResource: BackportPatchResource | null
  compareLeftPreview: PatchLoadState | null
  compareRightPreview: PatchLoadState | null
  manualPatchText: string
  onManualPatchTextChange: (value: string) => void
  manualPatchLoading: 'check' | 'apply' | null
  manualPatchResult: BackportOperationResultData | null
  attemptHistory: BackportAttemptSummary[]
  attemptHistoryLoading: boolean
  onCheckManualPatch: () => void
  onApplyManualPatch: () => void
  onUpdateMergedInTarget: (rowId: string, value: boolean | null) => void
  onCopyText: (text: string, label: string) => void
  onDownloadPatch: (preview: ReadyPatchLoadState) => void
  commitMessagePreviewLoading: boolean
  onRefreshCommitMessagePreview: (row: BackportCommitRow) => void
  onLoadPatchPreview: (
    row: BackportCommitRow,
    resource: BackportPatchResource,
    options?: { activate?: boolean }
  ) => Promise<ReadyPatchLoadState | null>
}

function DetailField({
  label,
  value,
  mono = false,
}: {
  label: string
  value: string
  mono?: boolean
}) {
  return (
    <div className="rounded-xl border border-slate-200/80 bg-white/80 px-3 py-2">
      <div className="text-[11px] font-semibold uppercase tracking-[0.14em] text-slate-500">
        {label}
      </div>
      <div className={cn('mt-1 text-sm text-slate-900', mono && 'break-all font-mono text-[12px]')}>
        {value || '--'}
      </div>
    </div>
  )
}

export function InspectorSheet({
  open,
  onOpenChange,
  row,
  config,
  inspectorTab,
  onInspectorTabChange,
  patchAnchorRefs,
  activePatchKey,
  activePatchPreview,
  compareLeftResource,
  compareRightResource,
  compareLeftPreview,
  compareRightPreview,
  manualPatchText,
  onManualPatchTextChange,
  manualPatchLoading,
  manualPatchResult,
  attemptHistory,
  attemptHistoryLoading,
  onCheckManualPatch,
  onApplyManualPatch,
  onUpdateMergedInTarget,
  onCopyText,
  onDownloadPatch,
  commitMessagePreviewLoading,
  onRefreshCommitMessagePreview,
  onLoadPatchPreview,
}: InspectorSheetProps) {
  const patchResources = row ? buildDisplayPatchResources(row.data, row.rowId) : []

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent
        side="right"
        className="w-[98vw] gap-0 sm:w-[94vw] sm:max-w-none xl:w-[88vw] 2xl:w-[84vw]"
      >
        {row ? (
          <>
            <SheetHeader className="border-b border-slate-200/80 bg-slate-50/70">
              <div className="pr-8">
                <SheetTitle className="text-left text-base text-slate-950">
                  {stringifyValue(row.data.commit || row.data.input_commit).slice(0, 12)} ·{' '}
                  {resolveCommitTitle(row.data) || '未命名提交'}
                </SheetTitle>
                <SheetDescription className="mt-1 text-left">
                  “详情预览”展示这一行 commit 的完整信息。
                </SheetDescription>
              </div>
            </SheetHeader>

            <div className="flex-1 overflow-hidden">
              <Tabs
                value={inspectorTab}
                onValueChange={value => onInspectorTabChange(value as InspectorTab)}
                className="flex h-full flex-col"
              >
                <div className="border-b border-slate-200/80 px-4 py-3">
                  <div className="flex flex-wrap items-center justify-between gap-3">
                    <TabsList className="grid w-full max-w-[680px] grid-cols-6">
                      <TabsTrigger value="details">详情</TabsTrigger>
                      <TabsTrigger value="history">历史</TabsTrigger>
                      <TabsTrigger value="patch">Patch</TabsTrigger>
                      <TabsTrigger value="compare">对比</TabsTrigger>
                      <TabsTrigger value="manual">手动 Patch</TabsTrigger>
                      <TabsTrigger value="yaml">原始 YAML</TabsTrigger>
                    </TabsList>

                    <div className="flex flex-wrap gap-1.5">
                      {patchResources.map(resource => (
                        <Button
                          key={resource.fileId}
                          variant="outline"
                          size="sm"
                          className="h-8 px-2 text-[11px]"
                          disabled={!resource.exists}
                          onClick={() => {
                            if (!resource.exists) return
                            void onLoadPatchPreview(row, resource)
                          }}
                        >
                          <Eye className="mr-1 h-3.5 w-3.5" />
                          {resource.label}
                        </Button>
                      ))}
                    </div>
                  </div>
                </div>

                <TabsContent value="details" className="mt-0 flex-1 overflow-auto px-4 py-4">
                  <div className="space-y-4">
                    <div className="rounded-2xl border border-slate-200/80 bg-white p-4 shadow-sm">
                      <div className="mb-3 flex items-center gap-2">
                        <FileCode2 className="h-4 w-4 text-blue-600" />
                        <h4 className="text-sm font-semibold text-slate-950">基本信息</h4>
                      </div>
                      <div className="grid gap-3 md:grid-cols-2">
                        <DetailField
                          label="完整 Commit"
                          value={stringifyValue(row.data.commit || row.data.input_commit)}
                          mono
                        />
                        <DetailField
                          label="提交时间"
                          value={formatGitDate(stringifyValue(row.data.committed_datetime))}
                        />
                        <DetailField
                          label="排序标签"
                          value={stringifyValue(row.data.git_describe) || '--'}
                          mono
                        />
                        <DetailField label="标题" value={resolveCommitTitle(row.data)} />
                        <DetailField
                          label="目标分支"
                          value={stringifyValue(
                            row.data.target_branch || config.target_release || '--'
                          )}
                        />
                      </div>
                    </div>

                    {(() => {
                      const sourceDetection =
                        row.data.source_detection && typeof row.data.source_detection === 'object'
                          ? (row.data.source_detection as Record<string, unknown>)
                          : {}
                      const preview = stringifyValue(row.data.commit_message_preview).trim()
                      const templateSnapshot = stringifyValue(
                        row.data.commit_message_template_snapshot
                      )
                      const previewStale =
                        Boolean(row.data.commit_message_preview_stale) ||
                        Boolean(
                          preview &&
                          templateSnapshot &&
                          templateSnapshot !== config.commit_message_template
                        )
                      const warnings = Array.isArray(row.data.commit_message_warnings)
                        ? row.data.commit_message_warnings
                            .map(item => stringifyValue(item))
                            .filter(Boolean)
                        : []
                      if (
                        !preview &&
                        Object.keys(sourceDetection).length === 0 &&
                        warnings.length === 0
                      )
                        return null
                      return (
                        <div className="rounded-2xl border border-slate-200/80 bg-white p-4 shadow-sm">
                          <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
                            <div className="flex items-center gap-2">
                              <FileCode2 className="h-4 w-4 text-violet-600" />
                              <h4 className="text-sm font-semibold text-slate-950">
                                Commit Message 预览
                              </h4>
                            </div>
                            <Button
                              variant="outline"
                              size="sm"
                              className={cn(
                                'h-8 px-2 text-[11px]',
                                previewStale &&
                                  'border-amber-200 bg-amber-50/70 text-amber-800 hover:bg-amber-100'
                              )}
                              disabled={commitMessagePreviewLoading}
                              onClick={() => onRefreshCommitMessagePreview(row)}
                            >
                              {commitMessagePreviewLoading ? (
                                <RefreshCw className="mr-1 h-3.5 w-3.5 animate-spin" />
                              ) : null}
                              刷新预览
                            </Button>
                          </div>
                          <div className="grid gap-3 md:grid-cols-3">
                            <DetailField
                              label="来源"
                              value={stringifyValue(sourceDetection.source) || '--'}
                            />
                            <DetailField
                              label="Commit ID"
                              value={stringifyValue(sourceDetection.commit_id) || '--'}
                              mono
                            />
                            <DetailField
                              label="识别依据"
                              value={stringifyValue(sourceDetection.method) || '--'}
                            />
                          </div>
                          {warnings.length > 0 ? (
                            <div className="mt-3 rounded-xl border border-amber-200 bg-amber-50/60 p-3 text-xs text-amber-900">
                              {warnings.join(';')}
                            </div>
                          ) : null}
                          {previewStale ? (
                            <div className="mt-3 rounded-xl border border-sky-200 bg-sky-50/70 p-3 text-xs text-sky-900">
                              模板已变更,此预览可能基于旧模板生成。可刷新当前行预览。
                            </div>
                          ) : null}
                          {preview ? (
                            <pre className="mt-3 max-h-72 overflow-auto whitespace-pre-wrap break-words rounded-xl border border-slate-200 bg-white p-4 font-mono text-[11px] leading-5 text-slate-800 shadow-inner">
                              {preview}
                            </pre>
                          ) : null}
                        </div>
                      )
                    })()}

                    <div className="rounded-2xl border border-slate-200/80 bg-white p-4 shadow-sm">
                      <div className="mb-3 flex items-center gap-2">
                        <CheckCircle2 className="h-4 w-4 text-emerald-600" />
                        <h4 className="text-sm font-semibold text-slate-950">检查结果</h4>
                      </div>
                      <div className="grid gap-3 md:grid-cols-2">
                        <DetailField label="状态" value={resolveStatusMeta(row.data).label} />
                        <DetailField label="冲突结果" value={resolveConflictMeta(row.data).label} />
                        <DetailField
                          label="冲突检查方式"
                          value={stringifyValue(row.data.conflict_check_method) || '--'}
                        />
                        <DetailField
                          label="已应用 Commit"
                          value={stringifyValue(row.data.applied_commit) || '--'}
                          mono
                        />
                        <DetailField
                          label="回移植进度"
                          value={resolveBackportProgressText(row.data)}
                        />
                        <DetailField
                          label="Merge Commit"
                          value={Boolean(row.data.is_merge_commit) ? '' : ''}
                        />
                        <DetailField
                          label="Empty Patch"
                          value={Boolean(row.data.empty_patch) ? '' : ''}
                        />
                        <DetailField
                          label="Equivalent Exists"
                          value={Boolean(row.data.equivalent_exists) ? '' : ''}
                        />
                        <div className="rounded-xl border border-slate-200/80 bg-white/80 px-3 py-2">
                          <div className="text-[11px] font-semibold uppercase tracking-[0.14em] text-slate-500">
                            目标分支结果
                          </div>
                          {isSkippedRow(row.data) ? (
                            <div className="mt-1 text-sm text-slate-700">已跳过</div>
                          ) : (
                            <select
                              value={
                                row.data.merged_in_target === true
                                  ? 'true'
                                  : row.data.merged_in_target === false
                                    ? 'false'
                                    : 'none'
                              }
                              onChange={event =>
                                onUpdateMergedInTarget(
                                  row.rowId,
                                  event.target.value === 'true'
                                    ? true
                                    : event.target.value === 'false'
                                      ? false
                                      : null
                                )
                              }
                              className="mt-1 h-9 w-full rounded-md border bg-background px-3 text-sm"
                            >
                              <option value="true">已合入</option>
                              <option value="false">未合入</option>
                              <option value="none">未设置</option>
                            </select>
                          )}
                        </div>
                      </div>

                      {stringifyValue(row.data.conflict_check_error).trim() ? (
                        <div className="mt-3 rounded-xl border border-amber-200 bg-amber-50/60 p-3">
                          <div className="text-[11px] font-semibold uppercase tracking-[0.14em] text-amber-700">
                            Conflict Check Error
                          </div>
                          <pre className="mt-2 whitespace-pre-wrap break-all font-mono text-[11px] leading-5 text-amber-900">
                            {stringifyValue(row.data.conflict_check_error)}
                          </pre>
                        </div>
                      ) : null}

                      {stringifyValue(row.data.merged_check_error).trim() ? (
                        <div className="mt-3 rounded-xl border border-slate-200 bg-slate-50/80 p-3">
                          <div className="text-[11px] font-semibold uppercase tracking-[0.14em] text-slate-600">
                            Merged Check Detail
                          </div>
                          <pre className="mt-2 whitespace-pre-wrap break-all font-mono text-[11px] leading-5 text-slate-700">
                            {stringifyValue(row.data.merged_check_error)}
                          </pre>
                        </div>
                      ) : null}

                      {stringifyValue(row.data.error).trim() ? (
                        <div className="mt-3 rounded-xl border border-red-200 bg-red-50/70 p-3">
                          <div className="text-[11px] font-semibold uppercase tracking-[0.14em] text-red-700">
                            Error
                          </div>
                          <pre className="mt-2 whitespace-pre-wrap break-all font-mono text-[11px] leading-5 text-red-900">
                            {stringifyValue(row.data.error)}
                          </pre>
                        </div>
                      ) : null}
                    </div>

                    <div className="rounded-2xl border border-slate-200/80 bg-white p-4 shadow-sm">
                      <div className="mb-3 flex items-center gap-2">
                        <FileCode2 className="h-4 w-4 text-blue-600" />
                        <h4 className="text-sm font-semibold text-slate-950">Patch 文件</h4>
                      </div>

                      <div className="grid gap-3 md:grid-cols-2">
                        {patchResources.map(resource => (
                          <div
                            key={resource.fileId}
                            className="rounded-xl border border-slate-200/80 bg-slate-50/50 p-3"
                          >
                            <div className="text-sm font-medium text-slate-900">
                              {resource.label}
                            </div>
                            <div className="mt-1 min-h-8 text-[11px] text-slate-500">
                              {resource.fileName || `${resource.label} 暂无`}
                            </div>
                            <div className="mt-3 flex gap-2">
                              <Button
                                variant="outline"
                                size="sm"
                                className="h-8 flex-1 px-2 text-[11px]"
                                disabled={!resource.exists}
                                onClick={() => {
                                  if (!resource.exists) return
                                  void onLoadPatchPreview(row, resource)
                                }}
                              >
                                查看
                              </Button>
                              <Button
                                variant="outline"
                                size="sm"
                                className="h-8 px-2 text-[11px]"
                                disabled={!resource.exists}
                                onClick={async () => {
                                  if (!resource.exists) return
                                  const preview = await onLoadPatchPreview(row, resource)
                                  if (preview) {
                                    onDownloadPatch(preview)
                                  }
                                }}
                              >
                                下载
                              </Button>
                            </div>
                          </div>
                        ))}
                      </div>
                    </div>

                    <Accordion
                      type="single"
                      collapsible
                      className="rounded-2xl border border-slate-200/80 bg-white px-4 shadow-sm"
                    >
                      <AccordionItem value="raw-yaml" className="border-0">
                        <AccordionTrigger className="text-sm font-semibold text-slate-950">
                          原始 YAML 字段
                        </AccordionTrigger>
                        <AccordionContent>
                          <pre className="overflow-auto whitespace-pre-wrap break-all rounded-xl border border-slate-200 bg-white p-4 font-mono text-[11px] leading-5 text-slate-800 shadow-inner">
                            {JSON.stringify(row.data, null, 2)}
                          </pre>
                        </AccordionContent>
                      </AccordionItem>
                    </Accordion>
                  </div>
                </TabsContent>

                <TabsContent value="history" className="mt-0 flex-1 overflow-auto px-4 py-4">
                  {attemptHistoryLoading ? (
                    <div className="flex h-48 items-center justify-center gap-2 text-sm text-slate-500">
                      <RefreshCw className="h-4 w-4 animate-spin" />
                      正在读取检查历史...
                    </div>
                  ) : attemptHistory.length === 0 ? (
                    <div className="flex h-48 items-center justify-center text-sm text-slate-500">
                      当前 commit 暂无已归档的检查记录。
                    </div>
                  ) : (
                    <div className="space-y-3">
                      {attemptHistory.map(attempt => {
                        const attemptRow = attempt.rows[0] || {}
                        const conflictText = attempt.conflict_report
                          ? JSON.stringify(attempt.conflict_report, null, 2)
                          : ''
                        return (
                          <section
                            key={`${attempt.attempt_dir}:${attempt.execution}:${attempt.attempt_number}`}
                            className="rounded-md border border-slate-200 bg-white p-4"
                          >
                            <div className="flex flex-wrap items-center justify-between gap-2">
                              <div className="flex items-center gap-2">
                                <History className="h-4 w-4 text-blue-600" />
                                <h4 className="text-sm font-semibold text-slate-950">
                                  {attempt.execution > 0
                                    ? `Run #${attempt.execution} · `
                                    : `Interaction #${attempt.attempt_number} · `}
                                  Case 记录
                                </h4>
                                <Badge variant="outline">
                                  {stringifyValue(attemptRow.status) || '未知状态'}
                                </Badge>
                              </div>
                              <span className="text-xs text-slate-500">
                                {attempt.updated_at || '--'}
                              </span>
                            </div>

                            {conflictText ? (
                              <div className="mt-4">
                                <div className="text-xs font-medium text-slate-700">
                                  OpenCode 冲突报告
                                </div>
                                <pre className="mt-2 max-h-72 overflow-auto whitespace-pre-wrap break-words rounded-md bg-slate-50 p-3 font-mono text-[11px] leading-5 text-slate-800">
                                  {conflictText}
                                </pre>
                              </div>
                            ) : null}

                            {attempt.patches.length > 0 ? (
                              <div className="mt-4">
                                <div className="text-xs font-medium text-slate-700">归档 Patch</div>
                                <div className="mt-2 space-y-1">
                                  {attempt.patches.map(patch => (
                                    <div
                                      key={`${attempt.attempt_number}:${patch.archive}`}
                                      className="break-all font-mono text-[11px] text-slate-600"
                                    >
                                      {patch.kind}: {patch.archive}
                                    </div>
                                  ))}
                                </div>
                              </div>
                            ) : null}

                            <div className="mt-4 grid gap-1 font-mono text-[11px] text-slate-500">
                              {attempt.report_path ? (
                                <div>report: {attempt.report_path}</div>
                              ) : null}
                              {attempt.stdout_path ? (
                                <div>stdout: {attempt.stdout_path}</div>
                              ) : null}
                              {attempt.stderr_path ? (
                                <div>stderr: {attempt.stderr_path}</div>
                              ) : null}
                            </div>
                          </section>
                        )
                      })}
                    </div>
                  )}
                </TabsContent>

                <TabsContent value="patch" className="mt-0 flex-1 overflow-hidden">
                  {!activePatchPreview ? (
                    <div className="flex h-full items-center justify-center px-6 text-center text-sm text-slate-500">
                      先从上方按钮选择一个 Patch,再在这里预览 diff、文件列表和 hunk 导航。
                    </div>
                  ) : activePatchPreview.status === 'loading' ? (
                    <div className="flex h-full items-center justify-center gap-2 text-sm text-slate-500">
                      <RefreshCw className="h-4 w-4 animate-spin" />
                      正在读取 Patch...
                    </div>
                  ) : activePatchPreview.status === 'error' ? (
                    <div className="flex h-full items-center justify-center px-6">
                      <div className="max-w-lg rounded-2xl border border-red-200 bg-red-50 p-4 text-sm text-red-700">
                        {activePatchPreview.error}
                      </div>
                    </div>
                  ) : (
                    <div className="flex h-full flex-col">
                      <div className="border-b border-slate-200/80 px-4 py-3">
                        <div className="flex flex-wrap items-start justify-between gap-3">
                          <div>
                            <div className="text-base font-semibold text-slate-950">
                              {activePatchPreview.resource.label} ·{' '}
                              {stringifyValue(row.data.commit || row.data.input_commit).slice(
                                0,
                                12
                              )}
                            </div>
                            <div className="mt-1 text-sm text-slate-500">
                              {activePatchPreview.response.file_name}
                            </div>
                          </div>
                          <div className="flex flex-wrap gap-2">
                            <Badge
                              variant="outline"
                              className="border-slate-200 bg-slate-50 text-slate-700"
                            >
                              影响文件 {activePatchPreview.summary.files.length}
                            </Badge>
                            <Badge
                              variant="outline"
                              className="border-emerald-200 bg-emerald-50 text-emerald-700"
                            >
                              +{activePatchPreview.summary.additions}
                            </Badge>
                            <Badge
                              variant="outline"
                              className="border-red-200 bg-red-50 text-red-700"
                            >
                              -{activePatchPreview.summary.deletions}
                            </Badge>
                            <Button
                              variant="outline"
                              size="sm"
                              className="h-8 px-2 text-[11px]"
                              onClick={() =>
                                onCopyText(
                                  activePatchPreview.response.patch_text,
                                  activePatchPreview.resource.label
                                )
                              }
                            >
                              <Copy className="mr-1 h-3.5 w-3.5" />
                              复制 Patch
                            </Button>
                            <Button
                              variant="outline"
                              size="sm"
                              className="h-8 px-2 text-[11px]"
                              onClick={() => onDownloadPatch(activePatchPreview)}
                            >
                              <Download className="mr-1 h-3.5 w-3.5" />
                              下载
                            </Button>
                          </div>
                        </div>
                      </div>

                      <div className="grid min-h-0 flex-1 gap-4 p-4 lg:grid-cols-[240px_minmax(0,1fr)] xl:grid-cols-[260px_minmax(0,1fr)]">
                        <div className="space-y-4 lg:overflow-auto lg:pr-2">
                          <div className="rounded-2xl border border-slate-200/80 bg-white p-4 shadow-sm">
                            <div className="text-sm font-semibold text-slate-950">文件列表</div>
                            <div className="mt-3 space-y-2">
                              {activePatchPreview.summary.files.length === 0 ? (
                                <div className="text-sm text-slate-500">
                                  当前 Patch 没有解析出文件变更。
                                </div>
                              ) : (
                                activePatchPreview.summary.files.map(file => (
                                  <div
                                    key={file.id}
                                    className="rounded-xl border border-slate-200/70 bg-slate-50/70 px-3 py-2"
                                  >
                                    <div className="break-all font-mono text-[11px] text-slate-900">
                                      {file.path}
                                    </div>
                                    <div className="mt-2 flex items-center gap-2 text-[11px]">
                                      <Badge
                                        variant="outline"
                                        className="border-emerald-200 bg-emerald-50 text-emerald-700"
                                      >
                                        +{file.additions}
                                      </Badge>
                                      <Badge
                                        variant="outline"
                                        className="border-red-200 bg-red-50 text-red-700"
                                      >
                                        -{file.deletions}
                                      </Badge>
                                      <Badge
                                        variant="outline"
                                        className="border-slate-200 bg-white text-slate-600"
                                      >
                                        hunk {file.hunkIds.length}
                                      </Badge>
                                    </div>
                                  </div>
                                ))
                              )}
                            </div>
                          </div>

                          <div className="rounded-2xl border border-slate-200/80 bg-white p-4 shadow-sm">
                            <div className="text-sm font-semibold text-slate-950">Hunk 导航</div>
                            <div className="mt-3 flex flex-wrap gap-2">
                              {activePatchPreview.summary.hunks.length === 0 ? (
                                <div className="text-sm text-slate-500">当前 Patch 没有 hunk。</div>
                              ) : (
                                activePatchPreview.summary.hunks.map((hunk, index) => (
                                  <Button
                                    key={hunk.id}
                                    variant="outline"
                                    size="sm"
                                    className="h-8 max-w-full px-2 text-[11px]"
                                    onClick={() => {
                                      const ref =
                                        patchAnchorRefs.current[`${activePatchKey}:${hunk.id}`]
                                      ref?.scrollIntoView({ behavior: 'smooth', block: 'center' })
                                    }}
                                  >
                                    #{index + 1}
                                  </Button>
                                ))
                              )}
                            </div>
                          </div>
                        </div>

                        <div className="min-h-0 overflow-hidden rounded-2xl border border-slate-200/80 bg-white shadow-sm">
                          <ScrollArea className="h-[calc(100vh-240px)] min-h-[520px] w-full">
                            <div className="min-w-0">
                              {activePatchPreview.summary.rawLines.map((line, index) => {
                                const matchedHunk =
                                  activePatchPreview.summary.hunks.find(
                                    hunk => hunk.lineIndex === index
                                  ) || null
                                const lineType = classifyPatchLine(line)

                                return (
                                  <div
                                    key={`${activePatchKey}:${index}`}
                                    ref={node => {
                                      if (matchedHunk) {
                                        patchAnchorRefs.current[
                                          `${activePatchKey}:${matchedHunk.id}`
                                        ] = node
                                      }
                                    }}
                                    className={cn(
                                      'flex border-b border-slate-100 font-mono text-[11px] leading-5',
                                      getLightPatchLineClass(lineType)
                                    )}
                                  >
                                    <span className="w-14 shrink-0 border-r border-slate-200 bg-slate-50 px-2 py-0.5 text-right text-slate-400">
                                      {index + 1}
                                    </span>
                                    <span className="flex-1 whitespace-pre-wrap break-all px-3 py-0.5">
                                      {line || ' '}
                                    </span>
                                  </div>
                                )
                              })}
                            </div>
                          </ScrollArea>
                        </div>
                      </div>
                    </div>
                  )}
                </TabsContent>

                <TabsContent value="compare" className="mt-0 flex-1 overflow-hidden">
                  {!compareLeftResource?.exists || !compareRightResource?.exists ? (
                    <div className="flex h-full items-center justify-center px-6 text-center text-sm text-slate-500">
                      当前条目缺少可对比的 Patch。建议至少保留“原始 Patch”和“待应用
                      Patch”再查看这里。
                    </div>
                  ) : (
                    <div className="flex h-full flex-col">
                      <div className="border-b border-slate-200/80 px-4 py-3">
                        <div className="flex flex-wrap items-start justify-between gap-3">
                          <div>
                            <div className="text-base font-semibold text-slate-950">
                              Patch 对比 ·{' '}
                              {stringifyValue(row.data.commit || row.data.input_commit).slice(
                                0,
                                12
                              )}
                            </div>
                            <div className="mt-1 text-sm text-slate-500">
                              左侧是源提交生成的原始 patch,右侧是当前点击“尝试应用”会使用的 patch。
                            </div>
                          </div>
                          <div className="flex flex-wrap gap-2 text-[11px] text-slate-500">
                            <Badge
                              variant="outline"
                              className="border-slate-200 bg-slate-50 text-slate-700"
                            >
                              原始 Patch
                            </Badge>
                            <Badge
                              variant="outline"
                              className="border-blue-200 bg-blue-50 text-blue-700"
                            >
                              待应用 Patch
                            </Badge>
                          </div>
                        </div>
                      </div>

                      <div className="grid min-h-0 flex-1 gap-4 p-4 xl:grid-cols-2">
                        {[
                          {
                            side: 'left',
                            resource: compareLeftResource,
                            preview: compareLeftPreview,
                          },
                          {
                            side: 'right',
                            resource: compareRightResource,
                            preview: compareRightPreview,
                          },
                        ].map(({ side, resource, preview }) => (
                          <div
                            key={side}
                            className="flex min-h-0 flex-col overflow-hidden rounded-2xl border border-slate-200/80 bg-white shadow-sm"
                          >
                            <div className="border-b border-slate-200/80 px-4 py-3">
                              <div className="flex flex-wrap items-start justify-between gap-3">
                                <div>
                                  <div className="text-sm font-semibold text-slate-950">
                                    {resource?.label || '--'}
                                  </div>
                                  <div className="mt-1 text-[11px] text-slate-500">
                                    {preview?.status === 'ready'
                                      ? preview.response.file_name
                                      : resource?.fileName || '未加载'}
                                  </div>
                                </div>
                                {preview?.status === 'ready' ? (
                                  <div className="flex flex-wrap gap-2">
                                    <Badge
                                      variant="outline"
                                      className="border-slate-200 bg-slate-50 text-slate-700"
                                    >
                                      文件 {preview.summary.files.length}
                                    </Badge>
                                    <Badge
                                      variant="outline"
                                      className="border-emerald-200 bg-emerald-50 text-emerald-700"
                                    >
                                      +{preview.summary.additions}
                                    </Badge>
                                    <Badge
                                      variant="outline"
                                      className="border-red-200 bg-red-50 text-red-700"
                                    >
                                      -{preview.summary.deletions}
                                    </Badge>
                                  </div>
                                ) : null}
                              </div>
                            </div>

                            {preview?.status === 'loading' || !preview ? (
                              <div className="flex flex-1 items-center justify-center gap-2 px-6 text-sm text-slate-500">
                                <RefreshCw className="h-4 w-4 animate-spin" />
                                正在读取 {resource?.label || 'Patch'}...
                              </div>
                            ) : preview.status === 'error' ? (
                              <div className="flex flex-1 items-center justify-center px-6">
                                <div className="max-w-lg rounded-2xl border border-red-200 bg-red-50 p-4 text-sm text-red-700">
                                  {preview.error}
                                </div>
                              </div>
                            ) : (
                              <div className="grid min-h-0 flex-1 gap-4 p-4 lg:grid-cols-[220px_minmax(0,1fr)]">
                                <div className="space-y-4 lg:overflow-auto lg:pr-2">
                                  <div className="rounded-2xl border border-slate-200/80 bg-slate-50/60 p-4">
                                    <div className="text-sm font-semibold text-slate-950">
                                      文件列表
                                    </div>
                                    <div className="mt-3 space-y-2">
                                      {preview.summary.files.length === 0 ? (
                                        <div className="text-sm text-slate-500">
                                          这个 Patch 没有解析出文件变更。
                                        </div>
                                      ) : (
                                        preview.summary.files.map(file => (
                                          <div
                                            key={`${side}-${file.id}`}
                                            className="rounded-xl border border-slate-200/70 bg-white px-3 py-2"
                                          >
                                            <div className="break-all font-mono text-[11px] text-slate-900">
                                              {file.path}
                                            </div>
                                            <div className="mt-2 flex items-center gap-2 text-[11px]">
                                              <Badge
                                                variant="outline"
                                                className="border-emerald-200 bg-emerald-50 text-emerald-700"
                                              >
                                                +{file.additions}
                                              </Badge>
                                              <Badge
                                                variant="outline"
                                                className="border-red-200 bg-red-50 text-red-700"
                                              >
                                                -{file.deletions}
                                              </Badge>
                                            </div>
                                          </div>
                                        ))
                                      )}
                                    </div>
                                  </div>
                                </div>

                                <div className="min-h-0 overflow-hidden rounded-2xl border border-slate-200/80 bg-white">
                                  <ScrollArea className="h-[calc(100vh-300px)] min-h-[460px] w-full">
                                    <div className="min-w-0">
                                      {preview.summary.rawLines.map((line, index) => {
                                        const lineType = classifyPatchLine(line)
                                        return (
                                          <div
                                            key={`${side}:${index}`}
                                            className={cn(
                                              'flex border-b border-slate-100 font-mono text-[11px] leading-5',
                                              getLightPatchLineClass(lineType)
                                            )}
                                          >
                                            <span className="w-14 shrink-0 border-r border-slate-200 bg-slate-50 px-2 py-0.5 text-right text-slate-400">
                                              {index + 1}
                                            </span>
                                            <span className="flex-1 whitespace-pre-wrap break-all px-3 py-0.5">
                                              {line || ' '}
                                            </span>
                                          </div>
                                        )
                                      })}
                                    </div>
                                  </ScrollArea>
                                </div>
                              </div>
                            )}
                          </div>
                        ))}
                      </div>
                    </div>
                  )}
                </TabsContent>

                <TabsContent value="manual" className="mt-0 flex-1 overflow-auto px-4 py-4">
                  <div className="space-y-4">
                    <div className="rounded-2xl border border-slate-200/80 bg-white p-4 shadow-sm">
                      <div className="mb-3 flex items-center justify-between gap-3">
                        <div>
                          <h4 className="text-sm font-semibold text-slate-950">手动 Patch</h4>
                          <p className="mt-1 text-xs text-slate-500">
                            当前会在目标仓目录执行 git apply --check,通过后再执行 git apply。
                          </p>
                        </div>
                        <Badge
                          variant="outline"
                          className="border-slate-200 bg-slate-50 text-slate-700"
                        >
                          {config.target_path || '未配置目标仓'}
                        </Badge>
                      </div>

                      <Textarea
                        value={manualPatchText}
                        onChange={event => onManualPatchTextChange(event.target.value)}
                        placeholder="把大模型修改后的 patch 粘贴到这里..."
                        className="min-h-[360px] resize-y font-mono text-[11px] leading-5"
                      />

                      <div className="mt-3 flex flex-wrap items-center justify-between gap-3">
                        <div className="text-xs text-slate-500">
                          {manualPatchText.trim()
                            ? `当前输入 ${manualPatchText.length} 字符`
                            : '粘贴 patch 后先检查是否能干净应用'}
                        </div>
                        <div className="flex gap-2">
                          <Button
                            variant="outline"
                            size="sm"
                            disabled={
                              manualPatchLoading !== null ||
                              !manualPatchText.trim() ||
                              !config.target_path.trim()
                            }
                            onClick={onCheckManualPatch}
                          >
                            {manualPatchLoading === 'check' ? (
                              <RefreshCw className="mr-1 h-4 w-4 animate-spin" />
                            ) : null}
                            检查冲突
                          </Button>
                          <Button
                            size="sm"
                            disabled={
                              manualPatchLoading !== null ||
                              !manualPatchText.trim() ||
                              !config.target_path.trim() ||
                              manualPatchResult?.operation !== 'check_manual_patch' ||
                              manualPatchResult.status !== 'success'
                            }
                            onClick={onApplyManualPatch}
                          >
                            {manualPatchLoading === 'apply' ? (
                              <RefreshCw className="mr-1 h-4 w-4 animate-spin" />
                            ) : null}
                            应用到目标仓
                          </Button>
                        </div>
                      </div>
                    </div>

                    {manualPatchResult ? (
                      <div
                        className={cn(
                          'rounded-2xl border p-4 shadow-sm',
                          manualPatchResult.status === 'success'
                            ? 'border-emerald-200 bg-emerald-50/60'
                            : 'border-red-200 bg-red-50/60'
                        )}
                      >
                        <div className="flex flex-wrap items-center gap-2">
                          <Badge
                            variant="outline"
                            className={cn(
                              manualPatchResult.status === 'success'
                                ? 'border-emerald-200 bg-white text-emerald-700'
                                : 'border-red-200 bg-white text-red-700'
                            )}
                          >
                            {manualPatchResult.status === 'success' ? '成功' : '失败'}
                          </Badge>
                          <div className="text-sm font-semibold text-slate-950">
                            {manualPatchResult.summary || '--'}
                          </div>
                        </div>
                        <pre className="mt-3 whitespace-pre-wrap break-all rounded-xl border border-slate-200 bg-white p-3 font-mono text-[11px] leading-5 text-slate-800">
                          {manualPatchResult.manual_patch?.stderr ||
                            manualPatchResult.manual_patch?.stdout ||
                            manualPatchResult.diagnostics?.error_text ||
                            '无额外输出'}
                        </pre>
                      </div>
                    ) : null}
                  </div>
                </TabsContent>

                <TabsContent value="yaml" className="mt-0 flex-1 overflow-auto px-4 py-4">
                  <pre className="overflow-auto whitespace-pre-wrap break-all rounded-2xl border border-slate-200 bg-white p-4 font-mono text-[11px] leading-5 text-slate-800 shadow-sm">
                    {JSON.stringify(row.data, null, 2)}
                  </pre>
                </TabsContent>
              </Tabs>
            </div>
          </>
        ) : (
          <div className="flex h-full items-center justify-center px-6 text-center text-sm text-slate-500">
            先在表格里选择一条 commit,再查看详情、Patch 预览或原始 YAML。
          </div>
        )}
      </SheetContent>
    </Sheet>
  )
}