import type {
  ButtonHTMLAttributes,
  HTMLAttributes,
  ReactNode,
  Ref,
} from "react";
import { useEffect, useRef } from "react";
import {
  ArrowLeft,
  Bot,
  CalendarDays,
  ChevronRight,
  MessageCircleMore,
  Paperclip,
  RotateCcw,
  Send,
  ShieldCheck,
  Watch,
  Activity,
} from "lucide-react";
import { useApp } from "./store";
import type { PlanItem, RouteId } from "./types";

export function Button({
  variant = "primary",
  className = "",
  ref,
  ...props
}: ButtonHTMLAttributes<HTMLButtonElement> & {
  variant?: "primary" | "secondary" | "ghost" | "danger";
  ref?: Ref<HTMLButtonElement>;
}) {
  return (
    <button
      ref={ref}
      className={`button button--${variant} ${className}`}
      {...props}
    />
  );
}

export function Card({
  children,
  className = "",
  onClick,
  ...props
}: { children: ReactNode; className?: string; onClick?: () => void } & Omit<
  HTMLAttributes<HTMLDivElement>,
  "onClick"
>) {
  return (
    <div
      {...props}
      className={`card ${onClick ? "card--clickable" : ""} ${className}`}
      onClick={onClick}
      role={onClick ? "button" : props.role}
      tabIndex={onClick ? 0 : undefined}
      onKeyDown={
        onClick
          ? (event) => {
              if (event.key === "Enter" || event.key === " ") {
                event.preventDefault();
                onClick();
              }
            }
          : undefined
      }
    >
      {children}
    </div>
  );
}

export function PageHeader({
  title,
  eyebrow,
  back = true,
  action,
  onBack,
  onTitleClick,
  titleActionLabel,
}: {
  title: string;
  eyebrow?: string;
  back?: boolean;
  action?: ReactNode;
  onBack?: () => void;
  onTitleClick?: () => void;
  titleActionLabel?: string;
}) {
  const { back: goBack } = useApp();
  return (
    <header className={`page-header ${back ? "" : "page-header--root"}`}>
      <div className="page-header__side">
        {back && (
          <button
            className="icon-button"
            aria-label="返回"
            onClick={onBack ?? goBack}
          >
            <ArrowLeft size={20} />
          </button>
        )}
      </div>
      <div className="page-header__title">
        {eyebrow && <span>{eyebrow}</span>}
        {onTitleClick ? (
          <button
            className="page-header__title-button"
            aria-label={titleActionLabel || title}
            onClick={onTitleClick}
          >
            <strong>{title}</strong>
          </button>
        ) : (
          <strong>{title}</strong>
        )}
      </div>
      <div className="page-header__side page-header__side--right">{action}</div>
    </header>
  );
}

export function BottomNavigation() {
  const { state, go } = useApp();
  const items: Array<{
    id: typeof state.activeTab;
    label: string;
    route: RouteId;
    image: string;
  }> = [
    {
      id: "training",
      label: "训练",
      route: "TRAIN-HUB",
      image: "/running-shoe-unbranded.png",
    },
    {
      id: "home",
      label: "首页",
      route: "HOME-01",
      image: "/nav-home-v24.png",
    },
    {
      id: "profile",
      label: "我的",
      route: "PROFILE-01",
      image: "/nav-profile-v24.png",
    },
  ];
  return (
    <nav className="bottom-nav" aria-label="一级导航">
      {items.map((item) => {
        const active = state.activeTab === item.id;
        return (
          <button
            key={item.id}
            className={`${active ? "is-active" : ""} ${item.id === "home" ? "is-primary" : ""}`}
            onClick={() => go(item.route, item.id)}
          >
            <img src={item.image} alt="" aria-hidden="true" />
            <span>{item.label}</span>
          </button>
        );
      })}
    </nav>
  );
}

export function AiSummary({
  title = "AI 总结",
  summary,
  onClick,
}: {
  title?: string;
  summary: string;
  onClick?: () => void;
}) {
  return (
    <div className="ai-summary">
      <div className="ai-summary__icon">
        <img src="/cpt-ai-coach-avatar-v4.png" alt="" aria-hidden="true" />
      </div>
      <div className="ai-summary__copy">
        <b>{title}</b>
        <p>{summary}</p>
      </div>
      {onClick && (
        <button className="go-see" onClick={onClick}>
          去看看 <ChevronRight size={14} />
        </button>
      )}
    </div>
  );
}

export function StatusBadge({
  tone = "green",
  children,
}: {
  tone?: "green" | "orange" | "blue" | "red" | "gray";
  children: ReactNode;
}) {
  return (
    <span className={`status-badge status-badge--${tone}`}>{children}</span>
  );
}

export function ScoreSlider({
  label,
  value,
  max = 20,
  onChange,
  hint,
}: {
  label: string;
  value: number;
  max?: number;
  onChange: (value: number) => void;
  hint: string;
}) {
  return (
    <div className="score-field">
      <div className="score-field__head">
        <b>{label}</b>
        <strong>
          {value}
          <span>/{max}</span>
        </strong>
      </div>
      <input
        aria-label={label}
        aria-describedby={`${label.replace(/\W/g, "")}-hint`}
        type="range"
        min="1"
        max={max}
        value={value}
        onChange={(event) => onChange(Number(event.target.value))}
      />
      <p id={`${label.replace(/\W/g, "")}-hint`}>{hint}</p>
    </div>
  );
}

export const Score20Slider = ScoreSlider;

export function Composer({
  value,
  onChange,
  onSend,
  placeholder = "今天想聊什么？直接告诉我…",
}: {
  value: string;
  onChange: (value: string) => void;
  onSend: () => void;
  placeholder?: string;
}) {
  const { patch } = useApp();
  return (
    <div className="composer">
      <input
        value={value}
        onChange={(event) => onChange(event.target.value)}
        onKeyDown={(event) => event.key === "Enter" && onSend()}
        placeholder={placeholder}
      />
      <button
        className="composer-attach"
        aria-label="添加附件"
        onClick={() => patch({ toast: "附件入口已经打开，可以把想让我一起看的内容发过来。" })}
      >
        <Paperclip size={20} />
      </button>
      <button className="composer-send" aria-label="发送" onClick={onSend}>
        <Send size={18} />
      </button>
    </div>
  );
}

export function EmptyState({
  icon = <Watch size={26} />,
  title,
  detail,
  action,
}: {
  icon?: ReactNode;
  title: string;
  detail: string;
  action?: ReactNode;
}) {
  return (
    <div className="empty-state">
      <div>{icon}</div>
      <b>{title}</b>
      <p>{detail}</p>
      {action}
    </div>
  );
}

export function SafetyBanner({ children }: { children: ReactNode }) {
  return (
    <div className="safety-banner">
      <ShieldCheck size={20} />
      <div>
        <b>安全提示</b>
        <p>{children}</p>
      </div>
    </div>
  );
}

export const demoItems = [
  {
    title: "首次建档与计划生成",
    detail: "登录 · 身高体重 · 出汗自评 · 生成计划",
    phase: "一期",
  },
  {
    title: "首页 Agent 与恢复建议",
    detail: "今日建议 · 快捷问题 · 历史对话",
    phase: "一期",
  },
  {
    title: "训练周期、调整与记录",
    detail: "阶段周期 · 周课表 · 历史记录 · 单次分析",
    steps: ["查看阶段周期", "打开周课表", "进入记录视图", "查看计划与实绩", "进入训练分析"],
    phase: "一期",
  },
  {
    title: "设备授权与数据同步",
    detail: "健康平台优先 · 权限 · 天气与恢复数据",
    phase: "一期·条件",
  },
  {
    title: "设备执行与训练后反馈",
    detail: "课表同步 · 设备执行 · 回传后 AI 复盘",
    phase: "一期·条件",
  },
  {
    title: "今日训练补给",
    detail: "训练前中后 · 补给时间 · 训练中提醒",
    steps: ["查看今日方案", "核对补给节点", "替换补给品", "AI 对话反馈完成情况"],
    phase: "一期",
  },
  {
    title: "数据 AI 总结与追问",
    detail: "去看看 · 带上下文问答 · 返回来源页",
    phase: "一期",
  },
  {
    title: "异常、冲突与安全状态",
    detail: "断网 · 权限 · 接口失败 · 安全阻断",
    phase: "一期",
  },
] as const;

export function DemoDock() {
  const { state, startDemo, reset } = useApp();
  return (
    <aside className="demo-dock">
      <div className="demo-dock__brand">
        <div className="brand-mark">
          <Activity size={21} />
        </div>
        <div>
          <b>跑步 AI 助手</b>
          <span>PRD V1.10 · 闭环原型</span>
        </div>
      </div>
      <div className="demo-dock__intro">
        <span>一期功能 Demo · D1–D8</span>
        <p>仅保留一期核心闭环；二期复杂分析不进入当前演示。</p>
      </div>
      <nav className="demo-list" aria-label="功能演示流程">
        {demoItems.map((item, index) => {
          const id = index + 1;
          return (
            <button
              key={item.title}
              className={state.demo === id ? "is-selected" : ""}
              onClick={() => startDemo(id)}
              aria-current={state.demo === id ? "step" : undefined}
              aria-label={`D${id} ${item.title}，${item.detail}，${item.phase}`}
            >
              <span>D{id}</span>
              <div>
                <b>{item.title}</b>
                <small>{item.detail}</small>
              </div>
              <span className="demo-list__phase">{item.phase}</span>
              <ChevronRight className="demo-list__arrow" size={15} />
            </button>
          );
        })}
      </nav>
      <Button variant="secondary" className="reset-button" onClick={reset}>
        <RotateCcw size={16} /> 一键重置演示
      </Button>
      <div className="adapter-note">
        <Bot size={17} />
        <p>
          <b>MockAdapter 已启用</b>
          <br />
          数据结构与正式 API 一致
        </p>
      </div>
    </aside>
  );
}

export function PhoneFrame({
  children,
  showBottomNav,
  toast,
  sessionBanner,
  overlay,
}: {
  children: ReactNode;
  showBottomNav: boolean;
  toast: string;
  sessionBanner?: ReactNode;
  overlay?: ReactNode;
}) {
  const { state } = useApp();
  const contentRef = useRef<HTMLElement>(null);
  const modalOpen = Boolean(overlay);
  useEffect(() => {
    contentRef.current?.scrollTo({ top: 0, behavior: "instant" });
  }, [state.route]);
  return (
    <div className="phone-wrap">
      <div className="phone-frame">
        <div className="phone-screen">
          <div className="status-bar">
            <span>9:41</span>
            <span className="dynamic-island" />
            <span>5G · 82%</span>
          </div>
          {sessionBanner && (
            <div className="phone-session-banner">{sessionBanner}</div>
          )}
          <main
            ref={contentRef}
            className={`screen-content ${showBottomNav ? "has-bottom-nav" : ""} ${sessionBanner ? "has-session-banner" : ""}`}
            inert={modalOpen ? true : undefined}
            aria-hidden={modalOpen ? "true" : undefined}
          >
            {children}
          </main>
          {toast && (
            <div className="toast" role="status">
              {toast}
            </div>
          )}
          {showBottomNav && (
            <div
              className="bottom-nav-lock"
              inert={modalOpen ? true : undefined}
              aria-hidden={modalOpen ? "true" : undefined}
            >
              <BottomNavigation />
            </div>
          )}
          {overlay && <div className="phone-modal-layer">{overlay}</div>}
          <div className="home-indicator" />
        </div>
      </div>
    </div>
  );
}

export function Metric({
  value,
  unit,
  label,
}: {
  value: string | number;
  unit?: string;
  label: string;
}) {
  return (
    <div className="metric">
      <strong>
        {value}
        <small>{unit}</small>
      </strong>
      <span>{label}</span>
    </div>
  );
}

export function SectionTitle({
  title,
  action,
}: {
  title: string;
  action?: ReactNode;
}) {
  return (
    <div className="section-title">
      <h2>{title}</h2>
      {action}
    </div>
  );
}

export function TimelineRail({
  icon,
  tone = "green",
}: {
  icon?: ReactNode;
  tone?: "green" | "orange" | "blue";
}) {
  return (
    <div className={`timeline-rail timeline-rail--${tone}`}>
      {icon ?? <MessageCircleMore size={15} />}
    </div>
  );
}

export function DateStrip({
  selected,
  onSelect,
  planItems = [],
  activityDates = [],
}: {
  selected: string;
  onSelect: (date: string) => void;
  planItems?: PlanItem[];
  activityDates?: string[];
}) {
  const start = new Date(`${selected}T12:00:00`);
  const mondayOffset = (start.getDay() + 6) % 7;
  start.setDate(start.getDate() - mondayOffset);
  const plannedByDate = new Map(planItems.map((item) => [item.date, item]));
  const completedDates = new Set(activityDates);
  const localIso = (date: Date) =>
    `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
  const days = Array.from({ length: 7 }, (_, i) => {
    const date = new Date(start);
    date.setDate(start.getDate() + i);
    const iso = localIso(date);
    const plan = plannedByDate.get(iso);
    const state = plan
      ? completedDates.has(iso) || plan.status === "completed"
        ? "done"
        : "planned"
      : completedDates.has(iso)
        ? "recorded"
        : "open";
    return {
      iso,
      week: "日一二三四五六"[date.getDay()],
      day: date.getDate(),
      state,
    };
  });
  return (
    <div className="date-strip" aria-label="本训练周安排">
      {days.map((d) => (
        <button
          key={d.iso}
          aria-label={`${d.iso}，${d.state === "done" ? "计划已完成" : d.state === "planned" ? "有训练安排" : d.state === "recorded" ? "有训练记录" : "无训练安排"}`}
          className={selected === d.iso ? "is-selected" : ""}
          onClick={() => onSelect(d.iso)}
        >
          <span>{d.week}</span>
          <b>{d.day}</b>
          <i className={`date-dot date-dot--${d.state}`}>
            {d.state === "done" ? "✓" : ""}
          </i>
        </button>
      ))}
    </div>
  );
}

export function CalendarIcon() {
  return <CalendarDays size={18} />;
}
