import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import Button, { ButtonType } from "../../../components/common/Button";
import Column from "../../../components/common/columns";
import Permission from "../../../components/common/Permission";
import { Paginated } from "../../../services/Paginated";
import FormsTable from "./components/formsTable";
import formsService, { GetFormResponse } from "./services/formsService";
import Loading from "../../../components/common/Loading";

const Forms: React.FC = () => {
  const { t } = useTranslation();

  const [loaded, setLoaded] = useState(false);
  const [pagedData, setPagedData] = useState<Paginated<GetFormResponse>>({
    page: 1,
    pageSize: 10,
    count: 0,
    totalPages: 1,
    data: [],
  });
  const [sortColumn, setSortColumn] = useState<Column<GetFormResponse>>({
    key: "name",
    label: t("Name"),
    order: "asc",
  });
  const [filters, setFilters] = useState<Map<string, string>>(
    new Map<string, string>(),
  );

  const changePage = useCallback(
    async (page: number, pageSize: number) => {
      const data = await formsService.getForms(
        page,
        pageSize,
        sortColumn.key,
        sortColumn.order === "asc",
        filters,
      );
      if (data) {
        setLoaded(true);
        setPagedData(data);
      } else {
        setLoaded(false);
      }
    },
    [filters, sortColumn.key, sortColumn.order],
  );

  const onSort = async (newSortColumn: Column<GetFormResponse>) => {
    const { page, pageSize } = pagedData;
    const data = await formsService.getForms(
      page,
      pageSize,
      newSortColumn.key,
      newSortColumn.order === "asc",
      filters,
    );
    if (data) {
      setLoaded(true);
      setPagedData(data);
      setSortColumn(newSortColumn);
    } else {
      setLoaded(false);
    }
  };

  const onSearch = async (name: string, value: string) => {
    const { page, pageSize } = pagedData;
    const newFilters = new Map(filters);
    newFilters.set(name, value);

    const data = await formsService.getForms(
      page,
      pageSize,
      sortColumn.key,
      sortColumn.order === "asc",
      newFilters,
    );
    if (data) {
      setLoaded(true);
      setFilters(newFilters);
      setPagedData(data);
    } else {
      setLoaded(false);
    }
  };

  const onDelete = async (item?: GetFormResponse) => {
    const response = await formsService.deleteForm(item?.id, item?.guid);
    if (response) {
      await changePage(pagedData.page, pagedData.pageSize);
    }
  };

  useEffect(() => {
    const loadInitial = async () => {
      const data = await formsService.getForms(1, 10, "name", true, filters);
      if (data) {
        setLoaded(true);
        setPagedData(data);
      } else {
        setLoaded(false);
      }
    };

    void loadInitial();
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <Loading loaded={loaded}>
      <Permission privilegeKey="AddFormTemplate">
        <div>
          <Button buttonType={ButtonType.primary} to="add">
            {t("Add")}
          </Button>
        </div>
      </Permission>
      <hr />
      <FormsTable
        data={pagedData}
        sortColumn={sortColumn}
        onChangePage={changePage}
        onSort={onSort}
        onSearch={onSearch}
        onDelete={onDelete}
      />
    </Loading>
  );
};

export default Forms;
