'use client';

import { useState, type ReactNode } from 'react';
import { cn } from '@/lib/utils';

// ──────────────────────────────────────────
// Tone palette
// ──────────────────────────────────────────
export const TONE: Record<
  string,
  { bg: string; text: string; ring: string; dot: string }
> = {
  teal: { bg: 'bg-teal-50', text: 'text-teal-700', ring: 'ring-teal-200', dot: 'bg-teal-500' },
  indigo: { bg: 'bg-indigo-50', text: 'text-indigo-700', ring: 'ring-indigo-200', dot: 'bg-indigo-500' },
  emerald: { bg: 'bg-emerald-50', text: 'text-emerald-700', ring: 'ring-emerald-200', dot: 'bg-emerald-500' },
  amber: { bg: 'bg-amber-50', text: 'text-amber-700', ring: 'ring-amber-200', dot: 'bg-amber-500' },
  rose: { bg: 'bg-rose-50', text: 'text-rose-700', ring: 'ring-rose-200', dot: 'bg-rose-500' },
  sky: { bg: 'bg-sky-50', text: 'text-sky-700', ring: 'ring-sky-200', dot: 'bg-sky-500' },
  violet: { bg: 'bg-violet-50', text: 'text-violet-700', ring: 'ring-violet-200', dot: 'bg-violet-500' },
  slate: { bg: 'bg-slate-100', text: 'text-slate-700', ring: 'ring-slate-200', dot: 'bg-slate-400' },
};
export const tone = (t?: string) => TONE[t ?? 'slate'] ?? TONE.slate!;

// ──────────────────────────────────────────
// Chip
// ──────────────────────────────────────────
export function Chip({
  children,
  tone: t = 'slate',
  className,
  icon,
  size = 'sm',
}: {
  children: ReactNode;
  tone?: string;
  className?: string;
  icon?: boolean;
  size?: 'xs' | 'sm';
}) {
  const T = tone(t);
  const pad = size === 'xs' ? 'px-1.5 py-0.5 text-[10.5px]' : 'px-2 py-0.5 text-[11px]';
  return (
    <span
      className={cn(
        'inline-flex items-center gap-1 rounded-full font-medium ring-1 ring-inset',
        pad,
        T.bg,
        T.text,
        T.ring,
        className,
      )}
    >
      {icon && <span className={cn('w-1.5 h-1.5 rounded-full', T.dot)} />}
      {children}
    </span>
  );
}

// ──────────────────────────────────────────
// PriorityBar — 5 段渐变,不显数字
// ──────────────────────────────────────────
export function PriorityBar({
  score,
  max = 100,
  segments = 5,
  label = '优先级',
}: {
  score: number;
  max?: number;
  segments?: number;
  label?: string;
}) {
  const pct = Math.max(0, Math.min(1, score / max));
  const filled = Math.max(1, Math.round(pct * segments));
  const level = pct >= 0.8 ? '极高' : pct >= 0.6 ? '高' : pct >= 0.4 ? '中' : pct >= 0.2 ? '低' : '极低';
  const levelTone = pct >= 0.8 ? 'rose' : pct >= 0.6 ? 'amber' : pct >= 0.4 ? 'amber' : 'emerald';
  const colors = ['bg-emerald-400', 'bg-emerald-500', 'bg-amber-400', 'bg-amber-500', 'bg-rose-500'];
  return (
    <div className="inline-flex items-center gap-2">
      <span className="text-[11px] text-slate-500">{label}</span>
      <div className="flex items-center gap-0.5">
        {Array.from({ length: segments }).map((_, i) => (
          <span
            key={i}
            className={cn('h-2 w-3 rounded-sm transition-colors', i < filled ? colors[i] : 'bg-slate-200')}
          />
        ))}
      </div>
      <Chip tone={levelTone} icon size="xs">
        {level}
      </Chip>
    </div>
  );
}

// ──────────────────────────────────────────
// AIStamp
// ──────────────────────────────────────────
export function AIStamp({
  label = 'AI 生成',
  relative,
  source = 'agent',
}: {
  label?: string;
  relative: string;
  source?: 'agent' | 'template_fallback' | 'manual';
}) {
  return (
    <span className="inline-flex items-center gap-1.5 text-[10.5px] text-indigo-600/80 font-medium">
      <span className="text-slate-500 tabular-nums">{relative}</span>
      {source === 'template_fallback' && (
        <Chip tone="amber" size="xs">
          兜底模板
        </Chip>
      )}
    </span>
  );
}

// ──────────────────────────────────────────
// Sidebar Card wrapper (可折叠)
// ──────────────────────────────────────────
export function SidebarCard({
  title,
  meta,
  action,
  children,
  className,
  defaultOpen = true,
  padding = 'p-2.5',
}: {
  title: string;
  meta?: string;
  action?: ReactNode;
  children: ReactNode;
  className?: string;
  defaultOpen?: boolean;
  padding?: string;
}) {
  const [open, setOpen] = useState(defaultOpen);
  return (
    <section
      className={cn(
        'bg-white rounded-lg border border-slate-100 shadow-sm flex flex-col min-h-0 flex-none',
        className,
      )}
    >
      <header className="flex-none px-3 pt-2 pb-1.5 flex items-center justify-between gap-2">
        <button
          onClick={() => setOpen(!open)}
          className="flex items-center gap-1.5 flex-1 min-w-0 text-left group"
        >
          <svg
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            strokeWidth="2"
            className={cn(
              'w-3 h-3 text-slate-400 group-hover:text-slate-600 transition-transform flex-none',
              !open && '-rotate-90',
            )}
          >
            <path d="M6 9l6 6 6-6" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
          <h3 className="text-[12px] font-semibold text-slate-900">{title}</h3>
          {meta && <span className="text-[10px] text-slate-400 truncate">· {meta}</span>}
        </button>
        {action && <div className="flex-none">{action}</div>}
      </header>
      {open && <div className={cn(padding, 'border-t border-slate-100 overflow-y-auto min-h-0')}>{children}</div>}
    </section>
  );
}

// ──────────────────────────────────────────
// Markdown(轻量 — ** bold / > blockquote / ### heading / - list)
// ──────────────────────────────────────────
function inlineMD(s: string): string {
  return s
    .replace(/`([^`]+)`/g, '<code class="px-1 py-px rounded bg-slate-100 text-slate-700 text-[12px] font-mono">$1</code>')
    .replace(/\*\*([^*]+)\*\*/g, '<strong class="font-semibold text-slate-900">$1</strong>');
}

export function MD({ text, className }: { text: string; className?: string }) {
  const lines = text.split('\n');
  const out: ReactNode[] = [];
  let i = 0;
  let key = 0; // ⭐ 顶层独立计数:不能用 i,因 blockquote/bullet 消费多行后 i 可能跟下一个 push 的 i 重复
  while (i < lines.length) {
    const line = lines[i]!;
    if (line.trim() === '') {
      i++;
      continue;
    }
    if (line.startsWith('### ')) {
      out.push(
        <h4 key={key++} className="text-[13px] font-semibold text-slate-900 mt-3">
          {line.slice(4)}
        </h4>,
      );
      i++;
    } else if (line.startsWith('## ')) {
      out.push(
        <h3 key={key++} className="text-[14px] font-semibold text-slate-900 mt-3">
          {line.slice(3)}
        </h3>,
      );
      i++;
    } else if (line.startsWith('> ')) {
      const block: string[] = [];
      while (i < lines.length && lines[i]!.startsWith('> ')) {
        block.push(lines[i]!.slice(2));
        i++;
      }
      out.push(
        <blockquote
          key={key++}
          className="my-2 pl-3 border-l-2 border-teal-300 bg-teal-50/40 py-2 pr-2 rounded-r text-[13px] text-slate-800 leading-relaxed"
        >
          {block.map((b, k) => (
            <p key={k} className="m-0" dangerouslySetInnerHTML={{ __html: inlineMD(b) }} />
          ))}
        </blockquote>,
      );
    } else if (line.startsWith('- ')) {
      const items: string[] = [];
      while (i < lines.length && lines[i]!.startsWith('- ')) {
        items.push(lines[i]!.slice(2));
        i++;
      }
      out.push(
        <ul key={key++} className="list-disc pl-5 my-1.5 text-[13px] text-slate-700 space-y-0.5">
          {items.map((t, k) => (
            <li key={k} dangerouslySetInnerHTML={{ __html: inlineMD(t) }} />
          ))}
        </ul>,
      );
    } else {
      out.push(
        <p
          key={key++}
          className="text-[13px] text-slate-700 leading-relaxed my-1"
          dangerouslySetInnerHTML={{ __html: inlineMD(line) }}
        />,
      );
      i++;
    }
  }
  return <div className={className}>{out}</div>;
}
