import React, { Fragment, useEffect, useState } from "react";
import { Button, Card, Col, Row, Table } from "react-bootstrap";

import {
  Column,
  Table as ReactTable,
  ColumnFiltersState,
  FilterFn,
  useReactTable,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  flexRender
} from '@tanstack/react-table';

import { rankItem } from '@tanstack/match-sorter-utils';

// Column Filter
const Filter = ({
  column
}: {
  column: Column<any, unknown>;
  table: ReactTable<any>;
}) => {
  const columnFilterValue = column.getFilterValue();

  return (
    <>
      <DebouncedInput
        type="text"
        value={(columnFilterValue ?? '') as string}
        onChange={value => column.setFilterValue(value)}
        placeholder="Search..."
        className="w-36 border shadow rounded"
        list={column.id + 'list'}
      />
      <div className="h-1" />
    </>
  );
};

// Global Filter
const DebouncedInput = ({
  value: initialValue,
  onChange,
  debounce = 500,
  ...props
}: {
  value: string | number;
  onChange: (value: string | number) => void;
  debounce?: number;
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'>) => {
  const [value, setValue] = useState(initialValue);

  useEffect(() => {
    setValue(initialValue);
  }, [initialValue]);

  useEffect(() => {
    const timeout = setTimeout(() => {
      onChange(value);
    }, debounce);

    return () => clearTimeout(timeout);
  }, [debounce, value]);


  return (
    <input 
      {...props} 
      value={value} 
      id="search-bar-0" 
      className="form-control search" 
      style={{
        border: '2px solid #e8e8e8',
        borderRadius: '8px',
        padding: '10px 40px 10px 15px',
        fontSize: '14px',
        transition: 'all 0.3s ease',
        boxShadow: '0 2px 4px rgba(0,0,0,0.05)'
      }}
      onFocus={(e) => {
        e.target.style.borderColor = 'orange';
        e.target.style.boxShadow = '0 0 0 3px rgba(255,165,0,0.1)';
      }}
      onBlur={(e) => {
        e.target.style.borderColor = '#e8e8e8';
        e.target.style.boxShadow = '0 2px 4px rgba(0,0,0,0.05)';
      }}
      onChange={e => setValue(e.target.value)} 
    />
  );
};

interface TableContainerProps {
  columns?: any;
  data?: any;
  isGlobalFilter?: any;
  handleTaskClick?: any;
  customPageSize?: any;
  tableClass?: any;
  theadClass?: any;
  trClass?: any;
  thClass?: any;
  divClass?: any;
  SearchPlaceholder?: any;
  handleLeadClick?: any;
  handleCompanyClick?: any;
  handleContactClick?: any;
  handleTicketClick?: any;
}

const TableContainer = ({
  columns,
  data,
  isGlobalFilter,
  customPageSize,
  tableClass,
  theadClass,
  trClass,
  thClass,
  divClass,
  SearchPlaceholder,

}: TableContainerProps) => {
  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
  const [globalFilter, setGlobalFilter] = useState('');

  const containsFilter: FilterFn<any> = (row, columnId, value, addMeta) => {
    const cellValue = row.getValue(columnId);
    if (cellValue == null) return false;
    return String(cellValue).toLowerCase().includes(String(value).toLowerCase());
  };

  const table = useReactTable({
    columns,
    data,
    filterFns: {
      contains: containsFilter,
    },
    state: {
      columnFilters,
      globalFilter,
    },
    onColumnFiltersChange: setColumnFilters,
    onGlobalFilterChange: setGlobalFilter,
    globalFilterFn: containsFilter,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getSortedRowModel: getSortedRowModel()
  });

  const {
    getHeaderGroups,
    getRowModel,
    getCanPreviousPage,
    getCanNextPage,
    getPageOptions,
    setPageIndex,
    nextPage,
    previousPage,
    setPageSize,
    getState
  } = table;

  useEffect(() => {
    Number(customPageSize) && setPageSize(Number(customPageSize));
  }, [customPageSize, setPageSize]);


    const pageSize = getState().pagination.pageSize;
    const totalRows = table.getFilteredRowModel().rows.length;
    const totalPages = Math.ceil(totalRows / pageSize);

    const [pageBlock, setPageBlock] = useState(0);getPageOptions
    const PAGES_PER_BLOCK = 10;

    const currentPage = getState().pagination.pageIndex;
    const totalBlocks = Math.ceil(totalPages / PAGES_PER_BLOCK);

    // Páginas visibles para el bloque actual
    const currentBlockPages = Array.from(
    { length: Math.min(PAGES_PER_BLOCK, totalPages - pageBlock * PAGES_PER_BLOCK) },
    (_, i) => pageBlock * PAGES_PER_BLOCK + i
    );

    useEffect(() => {
        const blockIndex = Math.floor(currentPage / PAGES_PER_BLOCK);
        if (blockIndex !== pageBlock) {
            setPageBlock(blockIndex);
        }
    }, [currentPage]);

  return (
    <Fragment>
      {isGlobalFilter && <Row className="mb-3">
        <Col xs={12}>
          <div 
            style={{
              background: 'linear-gradient(135deg, #fff7e6 0%, #ffffff 100%)',
              border: '2px solid orange',
              borderRadius: '12px',
              padding: '20px',
              boxShadow: '0 4px 12px rgba(255,165,0,0.15)',
              marginBottom: '15px'
            }}
          >
            <form>
              <Row>
                <Col xs={12} md={12} lg={12}>
                  <div style={{ position: 'relative' }}>
                    <label 
                      htmlFor="search-bar-0" 
                      style={{
                        display: 'block',
                        marginBottom: '8px',
                        fontWeight: 600,
                        color: '#333',
                        fontSize: '14px'
                      }}
                    >
                      <i className="bx bx-search-alt me-2" style={{ color: 'orange' }}></i>
                      Buscar...
                    </label>
                    <div className="flex">
                      <DebouncedInput style={{marginLeft: '40px'}}
                        value={globalFilter ?? ''}
                        onChange={value => setGlobalFilter(String(value))}
                        placeholder={SearchPlaceholder}
                      />
                      <i 
                        className="bx bx-search-alt search-icon" 
                        style={{
                          position: 'absolute',
                          right: '15px',
                          top: '70%',
                          transform: 'translateY(-50%)',
                          color: 'orange',
                          fontSize: '35px',
                          pointerEvents: 'none'
                        }}
                      ></i>
                    </div>
                  </div>
                </Col>
              </Row>
            </form>
          </div>
        </Col>
      </Row>}


      <div className={divClass}>
        <Table hover className={tableClass}>
          <thead className={theadClass}>
            {getHeaderGroups().map((headerGroup: any) => (
              <tr className={trClass} key={headerGroup.id}>
                {headerGroup.headers.map((header: any) => (
                  <th key={header.id} className={thClass}  {...{
                    onClick: header.column.getToggleSortingHandler(),
                  }}>
                    {header.isPlaceholder ? null : (
                      <React.Fragment>
                        {flexRender(
                          header.column.columnDef.header,
                          header.getContext()
                        )}
                        {{
                          asc: ' ',
                          desc: ' ',
                        }
                        [header.column.getIsSorted() as string] ?? null}
                        {header.column.getCanFilter() ? (
                          <div>
                            <Filter column={header.column} table={table} />
                          </div>
                        ) : null}
                      </React.Fragment>
                    )}
                  </th>
                ))}
              </tr>
            ))}
          </thead>

          <tbody>
            {getRowModel().rows.map((row: any) => {
              return (
                <tr key={row.id}>
                  {row.getVisibleCells().map((cell: any) => {
                    return (
                      <td key={cell.id}>
                        {flexRender(
                          cell.column.columnDef.cell,
                          cell.getContext()
                        )}
                      </td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </Table>
      </div>

      <Row className="align-items-center mt-2 g-3 text-center text-sm-start">
        <div className="col-sm">
          <div className="text-muted">Mostrando<span className="fw-semibold ms-1">{getState().pagination.pageSize>totalRows ? totalRows : getState().pagination.pageSize  }</span> of <span className="fw-semibold">{totalRows}</span> Resultados
          </div>
        </div>
       </Row>
       <Row className="align-items-center mt-2 g-3 text-center text-sm-start">
        <div className="col-sm">
          <ul className="pagination pagination-separated pagination-md justify-content-center justify-content-sm-start mb-0">
            <li className={!getCanPreviousPage() ? "page-item disabled" : "page-item"}>
            <Button
                className="page-link"
                onClick={() => {
                previousPage();
                const newPage = currentPage - 1;
                if (newPage < pageBlock * PAGES_PER_BLOCK) {
                    setPageBlock(Math.max(0, pageBlock - 1));
                }
                }}
                variant="link"
            >
                Anterior
            </Button>
            </li>

            {currentBlockPages.map((pageIndex) => (
            <li className="page-item" key={pageIndex}>
                <Button
                variant="link"
                className={currentPage === pageIndex ? "page-link active" : "page-link"}
                onClick={() => setPageIndex(pageIndex)}
                >
                {pageIndex + 1}
                </Button>
            </li>
            ))}

            <li className={!getCanNextPage() ? "page-item disabled" : "page-item"}>
            <Button
                className="page-link"
                onClick={() => {
                nextPage();
                const newPage = currentPage + 1;
                if (newPage >= (pageBlock + 1) * PAGES_PER_BLOCK) {
                    setPageBlock(Math.min(pageBlock + 1, totalBlocks - 1));
                }
                }}
                variant="link"
            >
                Siguiente
            </Button>
            </li>
          </ul>
        </div>
      </Row>
    </Fragment>
  );
};

export default TableContainer;
