import { useState, type ComponentType, type ReactNode } from 'react';
import { AlertCircle, Info, Loader2, SearchX, X } from 'lucide-react';
import { AnimatePresence, motion } from 'motion/react';
import { cn } from '../../lib/cn';

export type SurfaceIcon = ComponentType<{ size?: number; className?: string }>;

export function PageFrame({
  title,
  subtitle,
  icon: Icon,
  eyebrow,
  meta,
  actions,
  children,
  maxWidth = 'max-w-6xl',
  compactInfo = false,
}: {
  title: string;
  subtitle?: string;
  icon?: SurfaceIcon;
  eyebrow?: string;
  meta?: ReactNode;
  actions?: ReactNode;
  children: ReactNode;
  maxWidth?: string;
  compactInfo?: boolean;
}) {
  const [infoOpen, setInfoOpen] = useState(false);

  return (
    <div className="min-h-screen bg-[var(--app-bg)] text-slate-800 font-sans p-3 md:p-6 relative" style={{ overflowX: 'clip' }}>
      <div className={cn(maxWidth, 'mx-auto flex flex-col gap-4 pb-20 md:pb-6')}>
        <motion.header
          initial={{ opacity: 0, y: 10 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.28, ease: 'easeOut' }}
          className={cn(
            'relative rounded-2xl border border-white/70 bg-white/86 shadow-[0_18px_60px_rgba(15,23,42,0.08)] backdrop-blur-xl',
            compactInfo ? 'overflow-visible' : 'overflow-hidden',
          )}
        >
          <div className="absolute inset-x-0 top-0 h-1 bg-gradient-to-r from-blue-600 via-cyan-400 to-emerald-400" />
          {compactInfo ? (
            <>
              <div className="flex min-h-[48px] items-center gap-2 px-3 py-1.5 md:min-h-[54px] md:gap-3 md:px-4 md:py-2">
                {Icon ? (
                  <span className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-xl bg-blue-50 text-blue-600 ring-1 ring-blue-100 md:h-9 md:w-9">
                    <Icon size={17} />
                  </span>
                ) : null}
                <div className="min-w-0 flex-1">
                  <div className="flex min-w-0 items-center gap-2">
                    {eyebrow ? <span className="shrink-0 text-[11px] font-black text-blue-600">{eyebrow}</span> : null}
                    {meta ? <span className="hidden truncate text-[11px] font-bold text-slate-400 sm:inline">{meta}</span> : null}
                  </div>
                  <h1 className="mt-0.5 truncate text-base font-black tracking-tight text-slate-950 md:text-lg">{title}</h1>
                </div>
                {actions ? <div className="hidden shrink-0 items-center gap-2 md:flex">{actions}</div> : null}
                {subtitle ? (
                  <button
                    type="button"
                    onClick={() => setInfoOpen(open => !open)}
                    className={cn(
                      'inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-xl border text-slate-400 transition-colors md:h-9 md:w-9',
                      infoOpen ? 'border-blue-100 bg-blue-50 text-blue-600' : 'border-slate-100 bg-slate-50 hover:bg-blue-50 hover:text-blue-600',
                    )}
                    aria-label={infoOpen ? '收起页面说明' : '展开页面说明'}
                    title={infoOpen ? '收起说明' : '页面说明'}
                  >
                    {infoOpen ? <X size={16} /> : <Info size={16} />}
                  </button>
                ) : null}
              </div>
              <AnimatePresence initial={false}>
                {infoOpen && subtitle ? (
                  <motion.div
                    initial={{ height: 0, opacity: 0 }}
                    animate={{ height: 'auto', opacity: 1 }}
                    exit={{ height: 0, opacity: 0 }}
                    transition={{ duration: 0.18, ease: 'easeOut' }}
                    className="absolute left-0 right-0 top-full z-40 mt-2 overflow-hidden rounded-2xl border border-slate-100 bg-white shadow-xl md:static md:mt-0 md:rounded-none md:border-x-0 md:border-b-0 md:shadow-none"
                  >
                    <div className="px-4 py-3 text-xs font-bold leading-relaxed text-slate-500 md:text-sm">
                      {subtitle}
                    </div>
                  </motion.div>
                ) : null}
              </AnimatePresence>
            </>
          ) : (
            <div className="flex flex-col gap-4 p-4 md:flex-row md:items-end md:justify-between md:p-5">
              <div className="min-w-0">
                <div className="mb-2 flex flex-wrap items-center gap-2">
                  {Icon ? (
                    <span className="inline-flex h-8 w-8 items-center justify-center rounded-xl bg-blue-50 text-blue-600 ring-1 ring-blue-100">
                      <Icon size={17} />
                    </span>
                  ) : null}
                  {eyebrow ? <span className="text-[11px] font-black text-blue-600">{eyebrow}</span> : null}
                  {meta ? <span className="text-[11px] font-bold text-slate-400">{meta}</span> : null}
                </div>
                <h1 className="truncate text-xl font-black tracking-tight text-slate-950 md:text-2xl">{title}</h1>
                {subtitle ? <p className="mt-2 max-w-3xl text-xs font-bold leading-relaxed text-slate-500 md:text-sm">{subtitle}</p> : null}
              </div>
              {actions ? <div className="flex shrink-0 flex-wrap items-center gap-2">{actions}</div> : null}
            </div>
          )}
        </motion.header>
        {children}
      </div>
    </div>
  );
}

export function SurfaceCard({
  title,
  subtitle,
  actions,
  children,
  className,
}: {
  title?: string;
  subtitle?: string;
  actions?: ReactNode;
  children: ReactNode;
  className?: string;
}) {
  return (
    <section className={cn('rounded-2xl border border-slate-100 bg-white shadow-sm', className)}>
      {(title || subtitle || actions) && (
        <div className="flex flex-wrap items-start justify-between gap-3 border-b border-slate-100 px-4 py-3">
          <div>
            {title ? <h2 className="text-sm font-black text-slate-900">{title}</h2> : null}
            {subtitle ? <p className="mt-1 text-[11px] font-bold text-slate-400">{subtitle}</p> : null}
          </div>
          {actions ? <div className="flex items-center gap-2">{actions}</div> : null}
        </div>
      )}
      {children}
    </section>
  );
}

export function MetricTile({
  label,
  value,
  unit,
  helper,
  icon: Icon,
  tone = 'blue',
}: {
  label: string;
  value: ReactNode;
  unit?: string;
  helper?: string;
  icon?: SurfaceIcon;
  tone?: 'blue' | 'emerald' | 'amber' | 'rose' | 'slate';
}) {
  const toneClass = {
    blue: 'bg-blue-50 text-blue-600 ring-blue-100',
    emerald: 'bg-emerald-50 text-emerald-600 ring-emerald-100',
    amber: 'bg-amber-50 text-amber-600 ring-amber-100',
    rose: 'bg-rose-50 text-rose-600 ring-rose-100',
    slate: 'bg-slate-100 text-slate-600 ring-slate-200',
  }[tone];

  return (
    <div className="rounded-2xl border border-slate-100 bg-white p-4 shadow-sm transition-all hover:-translate-y-0.5 hover:shadow-md">
      <div className="flex items-start justify-between gap-3">
        <div className="min-w-0 text-[11px] font-black text-slate-400">{label}</div>
        {Icon ? (
          <span className={cn('inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-xl ring-1', toneClass)}>
            <Icon size={18} />
          </span>
        ) : null}
      </div>
      <div className="mt-3 flex min-w-0 items-end gap-1">
        <span className="min-w-0 whitespace-nowrap text-[clamp(1.65rem,6vw,2rem)] font-black leading-none tracking-tight text-slate-950 tabular-nums">
          {value}
        </span>
        {unit ? <span className="shrink-0 pb-0.5 text-[11px] font-black text-slate-400">{unit}</span> : null}
      </div>
      {helper ? <div className="mt-3 text-[11px] font-bold leading-relaxed text-slate-500">{helper}</div> : null}
    </div>
  );
}

export function SegmentedNav<T extends string>({
  tabs,
  active,
  onChange,
  className,
}: {
  tabs: readonly { id: T; label: string; icon?: SurfaceIcon }[];
  active: T;
  onChange: (id: T) => void;
  className?: string;
}) {
  return (
    <div className={cn('rounded-2xl border border-white/70 bg-white/90 p-1 shadow-sm backdrop-blur-xl', className)}>
      <div className="grid gap-1" style={{ gridTemplateColumns: `repeat(${tabs.length}, minmax(0, 1fr))` }}>
        {tabs.map(({ id, label, icon: Icon }) => {
          const isActive = active === id;
          return (
            <button
              key={id}
              type="button"
              onClick={() => onChange(id)}
              className={cn(
                'relative flex min-h-10 items-center justify-center gap-1.5 rounded-xl px-2 text-[12px] font-black transition-colors',
                isActive ? 'text-blue-700' : 'text-slate-400 hover:bg-slate-50 hover:text-slate-600',
              )}
            >
              {isActive ? (
                <motion.span
                  layoutId="segmented-active-pill"
                  className="absolute inset-0 rounded-xl bg-blue-50 shadow-sm ring-1 ring-blue-100"
                  transition={{ type: 'spring', stiffness: 430, damping: 34 }}
                />
              ) : null}
              {Icon ? <Icon size={15} className="relative" /> : null}
              <span className="relative truncate">{label}</span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

export function SkeletonBlock({ className }: { className?: string }) {
  return <div className={cn('overflow-hidden rounded-xl bg-slate-100 shimmer', className)} />;
}

export function LoadingState({ label = '数据加载中' }: { label?: string }) {
  return (
    <div className="rounded-2xl border border-slate-100 bg-white p-8 text-center shadow-sm">
      <Loader2 className="mx-auto mb-3 animate-spin text-blue-500" size={22} />
      <div className="text-xs font-black text-slate-500">{label}</div>
    </div>
  );
}

export function EmptyState({
  title = '暂无数据',
  description = '换个筛选条件或稍后再试',
}: {
  title?: string;
  description?: string;
}) {
  return (
    <div className="rounded-2xl border border-slate-100 bg-white p-8 text-center shadow-sm">
      <SearchX className="mx-auto mb-3 text-slate-300" size={26} />
      <div className="text-sm font-black text-slate-700">{title}</div>
      <div className="mt-1 text-xs font-bold text-slate-400">{description}</div>
    </div>
  );
}

export function ErrorState({ message }: { message: string }) {
  return (
    <div className="rounded-2xl border border-rose-100 bg-rose-50 p-4 text-rose-700 shadow-sm">
      <div className="flex items-start gap-2">
        <AlertCircle size={18} className="mt-0.5 shrink-0" />
        <div>
          <div className="text-sm font-black">加载失败</div>
          <div className="mt-1 text-xs font-bold leading-relaxed">{message}</div>
        </div>
      </div>
    </div>
  );
}

export function FadeIn({ children, className }: { children: ReactNode; className?: string }) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 8 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: -6 }}
      transition={{ duration: 0.22, ease: 'easeOut' }}
      className={cn('w-full min-w-0', className)}
    >
      {children}
    </motion.div>
  );
}
