import React from 'react';
import ColumnResizer from './ColumnResizer';

const getSortedColumns = (table) => {
  const allLeafColumns = table.getAllLeafColumns();
  const pinnedColumns = table.getState().columnPinning.left || [];

  return [...allLeafColumns].sort((a, b) => {
    const aIsPinned = pinnedColumns.includes(a.id);
    const bIsPinned = pinnedColumns.includes(b.id);

    if (aIsPinned && bIsPinned) {
      return pinnedColumns.indexOf(a.id) - pinnedColumns.indexOf(b.id);
    }
    if (aIsPinned) return -1;
    if (bIsPinned) return 1;
    return 0;
  });
};

const calculateLeftOffset = (table, columnOrHeader) => {
  const columnId =
    columnOrHeader.id.match(/data\..*$/)?.[0] || columnOrHeader.id;
  const pinnedColumns = table.getState().columnPinning.left || [];
  const currentPinnedIndex = pinnedColumns.indexOf(columnId);

  let leftOffset = 0;

  if (currentPinnedIndex > 0) {
    for (let i = 0; i < currentPinnedIndex; i++) {
      const prevColumn = table.getColumn(pinnedColumns[i]);
      if (prevColumn) {
        leftOffset += prevColumn.getSize();
      }
    }
  }

  return leftOffset;
};

const isColumnPin = (table, header) => {
  const pinningColumn = table.getState().columnPinning.left;
  //в header.id содержаться колонки по типу depth_idColParent_idChild, а в pinningColumn только idCol, которые закреплены
  //header.id.split('_').at(-1) - получение самой нижней колонки
  const columnId = header.id.match(/data\..*$/)?.[0] || header.id;
  const isPinned = pinningColumn.includes(columnId);
  return isPinned;
};
const ColumnNumbersRow = ({ table }) => {
  const sortedColumns = getSortedColumns(table);
  const tableState = table.getState();
  const filteredColumns = sortedColumns.filter(
    (col) =>
      !(col.id in tableState.columnVisibility) ||
      (col.id in tableState.columnVisibility &&
        tableState.columnVisibility[col.id]),
  );

  return (
    <div
      style={{
        display: 'flex',
        position: 'sticky',
        top: 0,
        zIndex: (theme) => theme.zIndex.table + 1,
        backgroundColor: 'white',
      }}
    >
      {filteredColumns.map((column) => (
        <ColumnNumberCell
          key={`col-number-${column.id}`}
          column={column}
          table={table}
        />
      ))}
    </div>
  );
};

const ColumnNumberCell = ({ column, table }) => {
  const isPinned = isColumnPin(table, column);
  const allLeafColumns = table.getAllLeafColumns();
  const originalIndex = allLeafColumns.findIndex((col) => col.id === column.id);
  const leftOffset = calculateLeftOffset(table, column);
  return (
    <div
      key={`col-number-${column.id}`}
      style={{
        width: column.getSize(),
        minWidth: column.getSize(),
        maxWidth: column.getSize(),
        padding: '2px 6px',
        textAlign: 'center',
        backgroundColor: isPinned ? '#f5f5f5' : '#F3F4F6',
        boxSizing: 'border-box',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        height: '1.5rem',
        border: '.063rem solid rgba(209, 213, 220, 1)',
        borderBottom: 'none',
        position: isPinned ? 'sticky' : 'relative',
        left: isPinned ? leftOffset : 'auto',
        zIndex: isPinned ? 20 : 'auto',
      }}
    >
      {originalIndex}
    </div>
  );
};

const HeaderCell = ({ header, table, onClick, hightlight, onChangeWidth }) => {
  const column = header.column;
  const isPinned = isColumnPin(table, header);
  const leftOffset = calculateLeftOffset(table, header);

  const customBgColor = column.columnDef?.muiTableHeadCellProps?.sx?.backgroundColor;
  const color = column.columnDef?.muiTableHeadCellProps?.sx?.color || '#000000';

  const backgroundColor = customBgColor
    ? customBgColor
    : (hightlight ? '#cbccce' : 'rgba(243, 244, 246, 1)');

  const handleChangeWidth = (deltaWidth) => {
    const size = header.getSize();
    onChangeWidth(header, size + deltaWidth);
  };

  // Вычисляем отступ для текста внутри ячейки
  // Если колонка закреплена, текст должен быть привязан к левому краю ячейки
  // Если колонка не закреплена, текст должен начинаться после всех закрепленных колонок
  const getTextLeftOffset = () => {
    if (isPinned) {
      return '0';
    }
    // Для незакрепленных колонок текст должен начинаться после всех закрепленных
    // Получаем общую ширину всех закрепленных колонок
    const pinnedColumns = table.getState().columnPinning.left || [];
    let totalPinnedWidth = 0;
    for (const pinnedId of pinnedColumns) {
      const pinnedCol = table.getColumn(pinnedId);
      if (pinnedCol) {
        totalPinnedWidth += pinnedCol.getSize();
      }
    }
    return `${totalPinnedWidth}px`;
  };

  return (
    <div
      style={{
        position: isPinned ? 'sticky' : 'relative',
        left: isPinned ? leftOffset : 'auto',
        zIndex: isPinned ? 21 : 'auto',
      }}
    >
      <div style={{ position: 'relative' }}>
        <div
          key={header.id}
          onClick={() => onClick(header)}
          style={{
            width: header.getSize() + 'px',
            minWidth: header.getSize() + 'px',
            maxWidth: header.getSize() + 'px',
            position: 'relative',
            padding: '4px 6px',
            textAlign: 'center',
            fontWeight: 600,
            fontSize: '12px',
            backgroundColor: backgroundColor,
            color: '#424242',
            boxSizing: 'border-box',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            height: '3rem',
            border: '.063rem solid rgba(209, 213, 220, 1)',
          }}
        >
          <div
            style={{
              textAlign: 'center',
              position: 'sticky',
              left: getTextLeftOffset(),
              right: 0,
              paddingRight: '0.5rem',
              paddingLeft: '0.5rem',
              backgroundColor: backgroundColor,
              color: color,
            }}
          >
            {header.isPlaceholder ? null : column.columnDef.header}
          </div>
          <ColumnResizer reportDragDeltaX={handleChangeWidth} />
        </div>
      </div>
    </div>
  );
};

const FilterRow = ({ table }) => {
  const sortedColumns = getSortedColumns(table);
  const tableState = table.getState();

  const filteredColumns = sortedColumns.filter(
    (col) =>
      !(col.id in tableState.columnVisibility) ||
      (col.id in tableState.columnVisibility &&
        tableState.columnVisibility[col.id]),
  );

  return (
    <div
      style={{
        display: 'flex',
        position: 'sticky',
        top: '1.5rem',
        zIndex: 20,
        backgroundColor: 'white',
      }}
    >
      {filteredColumns.map((column) => (
        <FilterCell key={`filter-${column.id}`} column={column} table={table} />
      ))}
    </div>
  );
};

// Компонент ячейки фильтра
const FilterCell = ({ column, table }) => {
  const isPinned = isColumnPin(table, column);
  const leftOffset = calculateLeftOffset(table, column);

  // Определяем тип фильтра на основе колонки
  const filterVariant = column.columnDef.filterVariant || 'text';

  // Для select фильтра
  const selectOptions = column.columnDef.filterSelectOptions || [];

  const handleFilterChange = (value) => {
    column.setFilterValue(value);
  };

  // Рендер разных типов фильтров
  const renderFilterInput = () => {
    switch (filterVariant) {
      case 'select':
        return (
          <select
            value={column.getFilterValue() ?? ''}
            onChange={(e) => handleFilterChange(e.target.value)}
            style={{
              width: '100%',
              padding: '4px 6px',
              fontSize: '11px',
              border: '1px solid #ddd',
              borderRadius: '4px',
              backgroundColor: 'white',
            }}
          >
            <option value="">Все</option>
            {selectOptions.map((option) => (
              <option key={option} value={option}>
                {option}
              </option>
            ))}
          </select>
        );

      case 'range': {
        // Для диапазона можно реализовать два поля
        const [min, max] = column.getFilterValue() || ['', ''];
        return (
          <div style={{ display: 'flex', gap: '4px' }}>
            <input
              type="number"
              placeholder="От"
              value={min}
              onChange={(e) => column.setFilterValue([e.target.value, max])}
              style={{ width: '50%', padding: '4px', fontSize: '11px' }}
            />
            <input
              type="number"
              placeholder="До"
              value={max}
              onChange={(e) => column.setFilterValue([min, e.target.value])}
              style={{ width: '50%', padding: '4px', fontSize: '11px' }}
            />
          </div>
        );
      }

      default: // 'text'
        return (
          <input
            type="text"
            value={column.getFilterValue() ?? ''}
            onChange={(e) => handleFilterChange(e.target.value)}
            placeholder="Поиск..."
            style={{
              width: '100%',
              padding: '4px 6px',
              fontSize: '11px',
              border: '1px solid #ddd',
              borderRadius: '4px',
              boxSizing: 'border-box',
            }}
          />
        );
    }
  };

  return (
    <div
      style={{
        width: column.getSize(),
        minWidth: column.getSize(),
        maxWidth: column.getSize(),
        padding: '4px 6px',
        backgroundColor: isPinned ? '#f5f5f5' : 'white',
        boxSizing: 'border-box',
        height: '2.5rem',
        border: '.063rem solid rgba(209, 213, 220, 1)',
        borderTop: 'none',
        position: isPinned ? 'sticky' : 'relative',
        left: isPinned ? leftOffset : 'auto',
        zIndex: isPinned ? 19 : 'auto',
      }}
    >
      {renderFilterInput()}
    </div>
  );
};

export const TableHead = ({
  table,
  onHeaderSelect,
  selectHeader,
  onChangeWidth,
  isLoadingData,
}) => {
  const handleHeaderClick = (header) => {
    onHeaderSelect(header);
  };

  if (!isLoadingData) {
    return <div></div>
  }

  return (
    <>
      <div
        style={{
          zIndex: (theme) => theme.zIndex.table,
          position: 'relative',
          width: 'max-content',
        }}
      >
        {/* Строка с номерами колонок */}
        <ColumnNumbersRow table={table} />

        {table.getState().showColumnFilters && <FilterRow table={table} />}

        {/* Существующие строки заголовков */}
        {table.getHeaderGroups().map((headerGroup) => (
          <div key={headerGroup.id} style={{ display: 'flex' }}>
            {headerGroup.headers.map((header) => (
              <React.Fragment key={header.id}>
                <HeaderCell
                  header={header}
                  hightlight={
                    selectHeader ? header.id == selectHeader.id : false
                  }
                  table={table}
                  onClick={handleHeaderClick}
                  onChangeWidth={onChangeWidth}
                />
              </React.Fragment>
            ))}
          </div>
        ))}
      </div>
    </>
  );
};
