"use client";

import cx from "classnames";
import React, { useId } from "react";

import ConditionalWrapper from "../../utils/ConditionalWrapper";
import { useStatic } from "../../utils/hooks";
import { Footer } from "./Footer";
import { Header } from "./Header";
import { Rows } from "./Rows";
import TableStatic from "./Table.static";
import TableContext from "./TableContext";
import { ExpandableRowsCaptions, TableHeader, TableRow } from "./types";

interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {
  /** Caption helps users with screen readers to find a table and understand what it's about and decide if they want to read it. */
  caption?: React.ReactNode;
  expandableRowsCaptions?: ExpandableRowsCaptions;
  /** Foot element for table */
  footers?: TableRow[];
  /** Labels for headers in the table. Value of the key in headers match with the key name in rows */
  headers: TableHeader[];
  /** Compact table only takes spaced needed to display its content */
  isCompact?: boolean;
  /** Enable responsive card layout below md breakpoint for better accessibility */
  isResponsive?: boolean;
  /** If table has horizontal scrollbar */
  isScrollable?: boolean;
  /** Different colors for even and odd rows. */
  isStriped?: boolean;
  /** rows to print out in the table. */
  rows: TableRow[];
  className?: string;
}

const CLASS_ROOT = "table";

const Table: React.FC<TableProps> = ({
  className,
  caption,
  headers,
  rows,
  footers,
  isCompact,
  isResponsive,
  isStriped,
  isScrollable,
  expandableRowsCaptions = {
    header: "Rozšíriteľný",
    emptyRow: "Nerozšíriteľný riadok",
  },
  ...other
}) => {
  const [tableRef] = useStatic(TableStatic);
  const idPrefix = useId();

  const classes = cx(
    CLASS_ROOT,
    {
      [`${CLASS_ROOT}--striped`]: isStriped,
      [`${CLASS_ROOT}--compact`]: isCompact,
      [`${CLASS_ROOT}--responsive`]: isResponsive,
    },
    className,
  );

  const captionId = `${idPrefix}-caption`;

  const expandableRows = {
    hasExpandableRows: rows.some(
      (row) => row && row.expand && row.expand.length > 0,
    ),
    expandableRowsCaptions,
  };

  const customRows = rows.map((row, rowIndex) => {
    if (row && row.expand) {
      return {
        ...row,
        expand: row.expand.map((expandableRow, expandIndex) => ({
          ...expandableRow,
          id: `${idPrefix}-row-${rowIndex}-${expandIndex}`,
        })),
      };
    }

    return row;
  });

  const context = {
    headers,
    footers,
    rows: customRows,
    expandableRows,
    isResponsive,
  };

  const table = (
    <TableContext.Provider value={context}>
      <ConditionalWrapper
        condition={isScrollable || false}
        wrapper={
          <div
            className={`${CLASS_ROOT}-scrollable`}
            role="group"
            {...(caption && { "aria-labelledby": captionId })}
          />
        }
      >
        <table
          ref={tableRef}
          className={classes}
          {...(isResponsive && { "data-table": "responsive" })}
          {...other}
        >
          {caption && (
            <caption {...(isScrollable && { id: captionId })}>
              {caption}
            </caption>
          )}
          <Header />
          <Rows />
          <Footer />
        </table>
      </ConditionalWrapper>
    </TableContext.Provider>
  );

  return table;
};

Table.displayName = "Table";

export { Table };
