// packages/core/src/components/data-table/data-table-context.ts
import type { Accessor } from "solid-js";
import { createContext, useContext } from "solid-js";
import type { DataTableColumn, SortDirection } from "./data-table.props";

/** Internal context value shared by all DataTable sub-components. */
export interface InternalDataTableContextValue {
  /** All column definitions (erased to unknown rows). */
  columns: Accessor<DataTableColumn<unknown>[]>;
  /** The current page of processed (sorted + filtered) rows. */
  pageData: Accessor<unknown[]>;
  /** Total number of pages. */
  pageCount: Accessor<number>;
  /** Current 0-based page index. */
  currentPage: Accessor<number>;
  /** Page size. */
  pageSize: Accessor<number>;
  /** Navigate to a page. */
  goToPage: (page: number) => void;
  /** Current sort column id, or undefined. */
  sortColumnId: Accessor<string | undefined>;
  /** Current sort direction. */
  sortDirection: Accessor<SortDirection>;
  /** Toggle sort on a column. Cycles: asc → desc → none. */
  toggleSort: (columnId: string) => void;
  /** Current filter string. */
  filterValue: Accessor<string>;
  /** Update the filter string. */
  setFilter: (value: string) => void;
  /** Set of selected original-data row indices. */
  selectedIndices: Accessor<Set<number>>;
  /** Toggle selection of a row by its index in the original data array. */
  toggleRowSelection: (index: number) => void;
  /** Whether row selection is enabled. */
  enableRowSelection: Accessor<boolean>;
  /** Whether multi-row selection is enabled. */
  enableMultiRowSelection: Accessor<boolean>;
  /** Total number of rows after filtering. */
  totalRows: Accessor<number>;
}

const InternalDataTableContext = createContext<InternalDataTableContextValue>();

/**
 * Returns the internal DataTable context.
 * Throws a descriptive error when called outside a DataTable root.
 */
export function useInternalDataTableContext(): InternalDataTableContextValue {
  const ctx = useContext(InternalDataTableContext);
  if (!ctx) {
    throw new Error(
      "[PettyUI] DataTable parts must be used inside <DataTable>.\n" +
        "  Fix: Wrap DataTable.Header, DataTable.Body, DataTable.Pagination inside <DataTable>.\n" +
        "  Docs: https://pettyui.dev/components/data-table#composition",
    );
  }
  return ctx;
}

export const InternalDataTableContextProvider = InternalDataTableContext.Provider;

/** Public context exposed via DataTable.useContext(). */
export interface DataTableContextValue {
  /** Current page data rows. */
  pageData: Accessor<unknown[]>;
  /** Current page index (0-based). */
  currentPage: Accessor<number>;
  /** Total number of pages. */
  pageCount: Accessor<number>;
  /** Current sort column id. */
  sortColumnId: Accessor<string | undefined>;
  /** Current sort direction. */
  sortDirection: Accessor<SortDirection>;
  /** Current filter string. */
  filterValue: Accessor<string>;
  /** Selected row indices. */
  selectedIndices: Accessor<Set<number>>;
}

const DataTableContext = createContext<DataTableContextValue>();

/**
 * Returns the public DataTable context.
 * Throws if called outside a DataTable root.
 */
export function useDataTableContext(): DataTableContextValue {
  const ctx = useContext(DataTableContext);
  if (!ctx) {
    throw new Error("[PettyUI] DataTable.useContext() called outside of <DataTable>.");
  }
  return ctx;
}

export const DataTableContextProvider = DataTableContext.Provider;
