import type { ContextMenuItem } from '#/components/context-menu';

export type CellType =
  | 'text'
  | 'number'
  | 'image'
  | 'video'
  | 'audio'
  | 'file'
  | 'readonly'
  | 'formula';

export interface CellRange {
  startRow: number;
  startCol: number;
  endRow: number;
  endCol: number;
}

export interface CellEditContext {
  fieldId: string;
  fieldValue: unknown;
  rowIndex: number;
  colIndex: number;
  rowKey: string | number;
  rowData: Record<string, unknown>;
  editParams: Record<string, unknown>;
  selection?: CellRange;
}

export interface HeaderContextMenuContext {
  colIndex: number;
  fieldId?: string;
  headerTitle: string;
  filterValue?: string;
}

export type ConditionalColorMode = 'background' | 'text' | 'both';

export type SpreadsheetTextAlign = 'left' | 'center' | 'right';

/** undefined | 'inherit' 均表示跟随全局 defaultTextAlign */
export type ColumnTextAlign = SpreadsheetTextAlign | 'inherit';

export interface ConditionalFormatRule {
  threshold: number;
  bgColor?: string;
  textColor?: string;
  colorMode?: ConditionalColorMode;
}

export interface ColumnConditionalFormat {
  gt?: ConditionalFormatRule;
  lt?: ConditionalFormatRule;
}

export interface SpreadsheetColumnConfig {
  fieldId: string;
  fieldName: string;
  cellType: CellType;
  col: number;
  editable?: boolean;
  formula?: string;
  suffix?: string;
  textAlign?: ColumnTextAlign;
  conditionalFormat?: ColumnConditionalFormat;
  onEdit?: (ctx: CellEditContext) => void | Promise<void>;
  onDoubleClick?: (ctx: CellEditContext) => void;
  editParams?: Record<string, unknown>;
  contextMenu?:
    | ContextMenuItem[]
    | ((ctx: CellEditContext) => ContextMenuItem[]);
}

export interface SpreadsheetHeaderConfig {
  title: string;
  col: number;
  fieldId?: string;
  filterable?: boolean;
  width?: number | 'auto';
  headerColor?: string;
  fixed?: boolean;
  contextMenu?:
    | ContextMenuItem[]
    | ((ctx: HeaderContextMenuContext) => ContextMenuItem[]);
}

export interface SpreadsheetLayoutState {
  colWidths?: Record<number, number>;
  headers?: Array<{
    col: number;
    headerColor?: string;
    fixed?: boolean;
  }>;
}

export interface SpreadsheetBatchCellChange {
  ctx: CellEditContext;
  before: unknown;
  after: unknown;
  col: number;
  viewRow: number;
}

export interface SpreadsheetTableConfig {
  tableName: string;
  sheetKey?: string;
  headers: SpreadsheetHeaderConfig[];
  enableFilter?: boolean;
  enableHistory?: boolean;
  rowHeight?: number | 'auto';
  defaultColWidth?: number;
  defaultTextAlign?: SpreadsheetTextAlign;
  onBatchEdit?: (changes: SpreadsheetBatchCellChange[]) => Promise<void>;
  onRefresh?: () => void | Promise<void>;
  headerContextMenu?:
    | ContextMenuItem[]
    | ((ctx: HeaderContextMenuContext) => ContextMenuItem[]);
}

export type SortDirection = 'asc' | 'desc';

export interface SpreadsheetColumnSort {
  col: number;
  direction: SortDirection;
}

/** checkedValues === undefined means all selected (no filter) */
export interface SpreadsheetColumnFilter {
  checkedValues?: string[];
}

export interface SpreadsheetViewState {
  filters: Record<number, SpreadsheetColumnFilter>;
  sort: SpreadsheetColumnSort | null;
}

export function createDefaultViewState(): SpreadsheetViewState {
  return { filters: {}, sort: null };
}

export interface SpreadsheetHistoryEntry {
  id: string;
  tableName: string;
  sheetKey?: string;
  userId: number;
  userName: string;
  action: 'edit' | 'fill' | 'paste' | 'rollback';
  rowKey: string | number;
  fieldId: string;
  beforeSnapshot: unknown;
  afterSnapshot: unknown;
  createdAt: string;
  synced: boolean;
}

export interface SpreadsheetCommand {
  label: string;
  undo: () => void | Promise<void>;
  redo: () => void | Promise<void>;
}

export interface ClipboardMatrix {
  rows: unknown[][];
  startRow: number;
  startCol: number;
}

export interface SpreadsheetEngineExpose {
  copy: (selectionOverride?: CellRange | CellRange[]) => void;
  copyAsImage: (selectionOverride?: CellRange | CellRange[]) => Promise<void>;
  paste: () => Promise<void>;
  undo: () => Promise<void>;
  redo: () => Promise<void>;
  canUndo: () => boolean;
  canRedo: () => boolean;
  canCopy: () => boolean;
  canCopyAsImage: () => boolean;
  canPaste: () => boolean;
  canEdit: (row: number, col: number) => boolean;
  getSelection: () => CellRange[];
  getCellEditContext: (row: number, col: number) => CellEditContext | null;
  getHeaderContext: (col: number) => HeaderContextMenuContext;
  setCellValue: (
    row: number,
    col: number,
    value: unknown,
    recordHistory?: boolean,
    action?: SpreadsheetHistoryEntry['action'],
  ) => Promise<void>;
  fillRange: (
    source: CellRange,
    target: CellRange,
  ) => Promise<void>;
  getColumnConfig: (col: number) => SpreadsheetColumnConfig | undefined;
  getFilterValue: (col: number) => string;
}

export const COLUMN_LETTER_HEIGHT = 22;
export const HEADER_TITLE_HEIGHT = 36;
export const HEADER_HEIGHT = COLUMN_LETTER_HEIGHT + HEADER_TITLE_HEIGHT;
export const ROW_NUMBER_WIDTH = 48;
export const DEFAULT_ROW_HEIGHT = 32;
export const DEFAULT_COL_WIDTH = 100;
export const MIN_COL_WIDTH = 60;
export const SCROLL_BUFFER_ROWS = 8;
