"use client";

import type { CSSProperties } from "react";
import type { TokenEntry } from "./read-tokens";
import styles from "./dev-test.module.scss";

/**
 * 토큰 **목록**은 CSSOM에서 읽으므로 여기에 적지 않는다. 이 표는 각 그룹을 어떻게
 * 보여줄지(색은 스와치, 길이는 막대, 나머지는 값)와 한글 이름만 정한다.
 * 목록에 없는 그룹이 새로 생겨도 값 표로 그려진다 — 빠지지 않는다.
 */
export const TOKEN_GROUPS: {
  key: string;
  label: string;
  kind: "swatch" | "bar" | "value";
  note?: string;
}[] = [
  {
    key: "color",
    label: "시맨틱 색상",
    kind: "swatch",
    note: "light/dark 값이 light-dark() 한 줄에 함께 정의돼 있습니다. 좌측 전환기로 두 테마를 대조해 보세요.",
  },
  { key: "theme", label: "브랜드 램프", kind: "swatch", note: "primary · secondary · accent" },
  {
    key: "primitive",
    label: "원시 팔레트",
    kind: "swatch",
    note: "화면에서 직접 쓰지 않는 바닥층입니다. 시맨틱 색상이 이 값들을 참조합니다.",
  },
  {
    key: "font",
    label: "서체",
    kind: "value",
    note: "size 계열은 768px 경계에서 값이 바뀝니다.",
  },
  { key: "padding", label: "패딩", kind: "bar" },
  { key: "gap", label: "간격", kind: "bar" },
  { key: "radius", label: "모서리 반경", kind: "bar" },
  { key: "icon", label: "아이콘 크기", kind: "bar" },
  { key: "border", label: "테두리 두께", kind: "bar" },
  { key: "number", label: "원시 수치", kind: "bar" },
  { key: "shadow", label: "그림자 수치", kind: "value" },
  { key: "backdrop", label: "배경 흐림", kind: "value" },
  { key: "form", label: "폼", kind: "value" },
  { key: "card", label: "카드", kind: "value" },
  { key: "modal", label: "모달", kind: "value" },
  { key: "grid", label: "그리드", kind: "value" },
  { key: "spacing", label: "여백", kind: "value" },
  { key: "section", label: "섹션", kind: "value" },
];

/**
 * ⚠️ 인라인 `style`을 쓰는 **유일하게 허용되는 예외**다. 개수를 미리 알 수 없는 토큰을
 * 런타임에 순회해야 하는데, CSS 클래스는 알 수 없는 이름에 대해 만들 수 없다. 여기서
 * 넣는 값은 디자인 값이 아니라 **토큰 참조**(`var(--fox-*)`)이며 실제 값은 여전히
 * 토큰이 소유한다. 일반 컴포넌트에서는 이 패턴을 쓰지 않는다.
 */
function ref(property: keyof CSSProperties, token: TokenEntry): CSSProperties {
  return { [property]: `var(${token.property})` } as CSSProperties;
}

function Swatches({ tokens, fn }: { tokens: TokenEntry[]; fn: string }) {
  return (
    <div className={styles.swatchGrid}>
      {tokens.map((token) => (
        <div key={token.property} className={styles.swatch}>
          <div className={styles.swatchChip} style={ref("background", token)} />
          <div className={styles.swatchMeta}>
            <span className={styles.tokenName}>
              fox.{fn}({token.name})
            </span>
            <span className={styles.tokenValue}>{token.value}</span>
          </div>
        </div>
      ))}
    </div>
  );
}

function ValueTable({
  tokens,
  fn,
  withBar,
}: {
  tokens: TokenEntry[];
  fn: string;
  withBar: boolean;
}) {
  return (
    <table className={styles.table}>
      <thead>
        <tr>
          <th scope="col">토큰</th>
          <th scope="col">값</th>
          {withBar ? <th scope="col">크기</th> : null}
        </tr>
      </thead>
      <tbody>
        {tokens.map((token) => (
          <tr key={token.property}>
            <td>
              fox.{fn}({token.name})
            </td>
            <td className={styles.tdValue}>{token.value}</td>
            {withBar ? (
              <td>
                <span className={styles.bar} style={ref("inlineSize", token)} />
              </td>
            ) : null}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

export function TokenView({ group, tokens }: { group: string; tokens: TokenEntry[] }) {
  const meta = TOKEN_GROUPS.find((entry) => entry.key === group);
  const kind = meta?.kind ?? "value";

  return (
    <section className={styles.section}>
      <h2 className={styles.sectionTitle}>
        {meta?.label ?? group} · {tokens.length}
      </h2>
      {meta?.note ? <p className={styles.sectionNote}>{meta.note}</p> : null}
      {kind === "swatch" ? (
        <Swatches tokens={tokens} fn={group} />
      ) : (
        <ValueTable tokens={tokens} fn={group} withBar={kind === "bar"} />
      )}
    </section>
  );
}
