import "react-data-grid/lib/styles.css";
import DataGrid, { SortDirection } from "react-data-grid";
import { useEffect, useMemo, useState } from "react";
import { Icon } from "../../tremor/Icon";
import { Title } from "../../tremor/Text";
import { FunnelIcon as FunnelIconOutline } from "@heroicons/react/24/outline";
import { FunnelIcon as FunnelIconSolid } from "@heroicons/react/24/solid";
import { BarsArrowDownIcon, BarsArrowUpIcon } from "@heroicons/react/20/solid";
import React from "react";
import { MultiSelect } from "../../tremor/MultiSelect";
import { useTheme } from "../../layouts/Dashboard/useTheme";
import { useBackend } from "../../layouts/Wrapper";

function urlify(text: string) {
  const markdownImageRegex = /!\[([^\]]*)\]\((https?:\/\/[^\s)]+)\)/g;
  const markdownLinkRegex = /\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g;
  const urlRegex = /(https?:\/\/[^\s]+)/g;

  let text1 = text + "";

  text1 = text1.replace(markdownImageRegex, (_, altText, url) => {
    let properUrl = url.startsWith("http") ? url : "https://" + url;
    return `<img style="height:28px;width:28px;object-fit:contain;object-position:50% 50%;" src="${properUrl}" alt="${altText}" />`;
  });

  text1 = text1.replace(markdownLinkRegex, (_, linkText, url) => {
    let properUrl = url.startsWith("http") ? url : "https://" + url;
    return `<a target="_blank" href="${properUrl}">${linkText}</a>`;
  });

  if (text1 !== text) {
    return text1;
  }

  return text1.replace(urlRegex, (url) => {
    let properUrl = url.startsWith("http") ? url : "https://" + url;
    return `<a target="_blank" href="${properUrl}">${url}</a>`;
  });
}

const cellRenderer = (obj: { row: any; column: any }) => {
  let content = urlify(obj.row[obj.column.key]);
  return <span dangerouslySetInnerHTML={{ __html: content }}></span>;
};

export interface TableChartProps {
  data: any;
  pagination?: {
    currentPage: number;
    pageSize: number;
    sortColumn?: string;
    sortDirection?: "ASC" | "DESC";
  };
  stats?: {
    totalPages: number;
  };
  setPagination?: React.Dispatch<
    React.SetStateAction<{
      currentPage: number;
      pageSize: number;
      sortColumn?: string;
      sortDirection?: "ASC" | "DESC";
    }>
  >;
  padding?: number;
}

export const TableChart: React.FC<TableChartProps> = ({
  data,
  pagination,
  setPagination,
  padding,
}) => {
  const [filterEnabled, setFilterEnabled] = useState(false);
  const [options, setOptions] = useState<{ [key: string]: string[] }>({});
  const [filters, setFilters] = useState<{ [key: string]: string[] }>({});
  const theme = useTheme();
  const { containerRef } = useBackend();


  let [allObjects, fields] = useMemo(() => {
    let newRows: any[] = [];
    let label = data.options?.scales?.x?.title?.text || "Label";
    data.data.datasets[0].data.map((item: any, i: number) => {
      let row: any = {};
      if (data.data.labels && data.data.labels[i]) {
        row = {
          [label]: data.data.labels[i],
        };
      }
      data.data.datasets.map((a: any, j: number) => {
        row[a.label] = a.data[i];
      });
      newRows.push(row);
    });

    if (data.data.labels) {
      let newFields: string[] = [
        label,
        ...data.data.datasets.map((a: any) => a.label),
      ];
      return [newRows, newFields];
    } else {
      let newFields: string[] = data.data.datasets.map((a: any) => a.label);
      return [newRows, newFields];
    }

  }, [data]);

  let objects = useMemo(() => {
    let newRows = [...allObjects];

    // Filter newRows based on filters
    if (filters) {
      newRows = newRows.filter((row) => {
        let pass = true;
        Object.keys(filters).forEach((key) => {
          if (filters[key].length > 0 && !filters[key].includes(row[key])) {
            pass = false;
          }
        });
        return pass;
      });
    }

    // Sort newRows here based on pagination data
    if (pagination) {
      const { sortColumn, sortDirection } = pagination;
      if (sortColumn && sortDirection) {
        newRows.sort((a, b) => {
          const valueA = a[sortColumn];
          const valueB = b[sortColumn];

          if (valueA < valueB) {
            return sortDirection === "ASC" ? -1 : 1;
          }
          if (valueA > valueB) {
            return sortDirection === "ASC" ? 1 : -1;
          }
          return 0;
        });
      }
    }
    return newRows;
  }, [allObjects, filters]);

  useEffect(() => {
    let newOptions: { [key: string]: string[] } = {};
    fields.forEach((field) => {
      newOptions[field] = [];
      allObjects.forEach((row) => {
        if (!newOptions[field].includes(row[field])) {
          newOptions[field].push(row[field]);
        }
      });
      newOptions[field].sort();

    });
    setOptions(newOptions);
  }, [allObjects, fields]);

  const handleSortChange = (newSorting: {
    columnKey: string;
    direction: SortDirection;
  }[]) => {
    if (!setPagination || !pagination) {
      return;
    }
    if (newSorting.length > 0) {
      const { columnKey, direction } = newSorting[0];
      setPagination({
        ...pagination,
        sortColumn: columnKey,
        sortDirection: direction,
        currentPage: 1,
      });
    } else {
      setPagination({
        ...pagination,
        sortColumn: undefined,
        sortDirection: undefined,
      });
    }
  };


  const columns = useMemo(() => {
    return Object.keys(options).map((a) => ({
      key: a,
      name: a,
      renderCell: cellRenderer,
      renderHeaderCell: (p: any) => {
        const isMatchingFilterColumn = pagination?.sortColumn === p.column.name;
        const filterTypeClass = isMatchingFilterColumn
          ? "onvo-table-widget-filter-active"
          : "onvo-table-widget-filter-inactive";
        return (
          <div
            className="onvo-table-widget-header onvo-flex onvo-h-full onvo-flex-col onvo-justify-center onvo-gap-2"
            style={{ lineHeight: "12px" }}
          >
            <div className="onvo-table-widget-header-title onvo-flex onvo-flex-row onvo-items-center onvo-justify-between">
              {p.column.name}
              <div className={`${filterTypeClass} onvo-flex onvo-flex-row`}>
                {isMatchingFilterColumn && (
                  <Icon
                    icon={
                      pagination?.sortDirection === "ASC"
                        ? BarsArrowUpIcon
                        : BarsArrowDownIcon
                    }
                    size="sm"
                  />
                )}
                <Icon
                  onClick={(e) => {
                    setFilterEnabled((a) => !a);
                    e.preventDefault();
                    e.stopPropagation();
                  }}
                  icon={filterEnabled ? FunnelIconSolid : FunnelIconOutline}
                  size="sm"
                />
              </div>
            </div>
            {filterEnabled && (
              <MultiSelect
                container={containerRef?.current}
                placeholder="Filter"
                className="-onvo-mt-2"
                onValueChange={(val) => {
                  setFilters({
                    ...filters,
                    [p.column.key]: val,
                  });
                }}
                items={options[a].map((c) => ({
                  label: c,
                  value: c,
                }))}
              />
            )}
          </div>
        );
      },
    }));
  }, [options, filterEnabled, pagination]);

  const sortColumns = useMemo(() => {
    if (pagination && pagination.sortColumn) {
      return [{ columnKey: pagination.sortColumn, direction: pagination.sortDirection || "ASC" }];
    }
    return [];
  }, [pagination]);


  return (
    <div style={{ padding: (padding) + "px" }} className="onvo-table-widget onvo-h-full onvo-flex onvo-flex-col onvo-relative">
      <Title className="onvo-table-widget-title onvo-text-md onvo-font-override onvo-my-0">
        {data.options.plugins.title.text}
      </Title>
      <DataGrid
        className={
          "onvo-table-widget-data-grid onvo-fill-grid onvo-mt-3 onvo-h-full onvo-rounded-xl onvo-border-solid onvo-border onvo-border-gray-200 dark:onvo-border-gray-800 " +
          (theme === "dark" ? "rdg-dark" : "rdg-light")
        }
        defaultColumnOptions={{
          sortable: true,
          resizable: true,
        }}
        enableVirtualization={true}
        headerRowHeight={filterEnabled ? 80 : 35}
        onSortColumnsChange={handleSortChange}
        sortColumns={sortColumns}
        columns={columns}
        rows={objects}
      />
    </div>
  );
};