"use client";

import {
  Children,
  Fragment,
  isValidElement,
  type ReactElement,
  type ReactNode,
} from "react";
import { cx } from "../../utils";
import type { FoxTableRowProps } from "../fox-table-row";

export type FoxTableType = "basic" | "list" | "form";

export interface FoxTableProps {
  /** `FoxTableRow`들. 머리행은 `head`를 주면 되고 순서는 신경 쓰지 않아도 된다. */
  children?: ReactNode;
  /**
   * `basic`은 제목 열이 있는 상세표, `list`는 목록표, `form`은 레이블 + 입력표다.
   * 여백·글자·기본 정렬이 이 값에 따라 달라진다.
   */
  type?: FoxTableType;
  /** 표가 무엇을 담는지. `<caption>`으로 나가며 화면에는 보이지 않는다. */
  caption?: string;
  /** 참이면 렌더하지 않는다(DOM에 남지 않는다). */
  hidden?: boolean;
  /** 배치 조정용. */
  className?: string;
}

type RowElement = ReactElement<FoxTableRowProps>;

/** 프래그먼트 안까지 훑어 행을 모은다. */
function collectRows(children: ReactNode): RowElement[] {
  const rows: RowElement[] = [];
  Children.forEach(children, (child) => {
    if (!isValidElement(child)) {
      return;
    }
    if (child.type === Fragment) {
      const fragment = child as ReactElement<{ children?: ReactNode }>;
      rows.push(...collectRows(fragment.props.children));
      return;
    }
    rows.push(child as RowElement);
  });
  return rows;
}

/**
 * @fox 표. 진짜 `<table>`이라 스크린리더가 몇 행 몇 열인지 읽어 주고 `colSpan`·`rowSpan`이
 * 그대로 동작한다.
 *
 * 호출부는 행을 늘어놓기만 하면 된다 — 머리행(`head`)은 `<thead>`로, 나머지는 `<tbody>`로
 * 알아서 갈린다.
 *
 * 좁은 화면에서는 `list`가 한 줄씩 카드로 접히고 `form`은 레이블이 입력 위로 올라간다
 * (시안의 device 축). 그 전환은 CSS가 화면 폭을 보고 하므로 프롭이 없다.
 *
 * ⚠️ 스타일은 이 파일이 import하지 않는다 — 호스트 앱이 `@use "@fox/styles/components"`
 * (또는 개별 파티셜)로 한 번 불러와야 한다.
 */
export function FoxTable({
  children,
  type = "basic",
  caption,
  hidden = false,
  className,
}: FoxTableProps) {
  if (hidden) {
    return null;
  }

  const rows = collectRows(children);
  const headRows = rows.filter((row) => row.props.head);
  const bodyRows = rows.filter((row) => !row.props.head);

  return (
    <table className={cx("fox-table", `fox-table--${type}`, className)}>
      {caption && <caption className="fox-table__caption">{caption}</caption>}
      {headRows.length > 0 && <thead className="fox-table__head">{headRows}</thead>}
      {bodyRows.length > 0 && <tbody className="fox-table__body">{bodyRows}</tbody>}
    </table>
  );
}
