/*!
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
import { Box, HStack, Skeleton, Spacer } from "@chakra-ui/react";
import { createListCollection } from "@chakra-ui/react/collection";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useSearchParams } from "react-router-dom";

import { usePoolServiceGetPools } from "openapi/queries";
import type { PoolResponse } from "openapi/requests/types.gen";
import { DataTable } from "src/components/DataTable";
import type { CardDef } from "src/components/DataTable/types";
import { useTableURLState } from "src/components/DataTable/useTableUrlState";
import { ErrorAlert } from "src/components/ErrorAlert";
import { SearchBar } from "src/components/SearchBar";
import { Select } from "src/components/ui";
import type { SearchParamsKeysType } from "src/constants/searchParams";
import { SearchParamsKeys } from "src/constants/searchParams";
import { useAdvancedSearch } from "src/hooks/useAdvancedSearch";

import AddPoolButton from "./AddPoolButton";
import PoolBarCard from "./PoolBarCard";

const cardDef = (): CardDef<PoolResponse> => ({
  card: ({ row }) => <PoolBarCard key={row.name} pool={row} />,
  meta: {
    customSkeleton: <Skeleton height="100px" width="100%" />,
  },
});

export const Pools = () => {
  const { t: translate } = useTranslation(["admin", "common"]);

  const poolSortOptions = createListCollection({
    items: [
      { label: translate("pools.sort.asc"), value: "name" },
      { label: translate("pools.sort.desc"), value: "-name" },
    ],
  });
  const [searchParams, setSearchParams] = useSearchParams();
  const { NAME_PATTERN, OFFSET }: SearchParamsKeysType = SearchParamsKeys;
  const [poolNamePattern, setPoolNamePattern] = useState(searchParams.get(NAME_PATTERN) ?? undefined);
  const advancedSearch = useAdvancedSearch("pools");

  const { setTableURLState, tableURLState } = useTableURLState();
  const { pagination, sorting } = tableURLState;
  const [sort] = sorting;
  const orderBy = sort ? [`${sort.desc ? "-" : ""}${sort.id}`] : ["name"];

  const { data, error, isLoading } = usePoolServiceGetPools({
    limit: pagination.pageSize,
    offset: pagination.pageIndex * pagination.pageSize,
    orderBy,
    ...(advancedSearch.enabled
      ? { poolNamePattern: poolNamePattern ?? undefined }
      : { poolNamePrefixPattern: poolNamePattern ?? undefined }),
  });

  const handleSearchChange = (value: string) => {
    if (value) {
      searchParams.set(NAME_PATTERN, value);
    } else {
      searchParams.delete(NAME_PATTERN);
    }
    searchParams.delete(OFFSET);
    setSearchParams(searchParams);
    setPoolNamePattern(value);
  };

  const handleSortChange = (details: { value: Array<string> }) => {
    const [firstValue] = details.value;

    if (firstValue !== undefined && firstValue !== "") {
      setTableURLState({
        ...tableURLState,
        sorting: [{ desc: firstValue.startsWith("-"), id: firstValue.replace("-", "") }],
      });
    }
  };

  return (
    <>
      <ErrorAlert error={error} />
      <SearchBar
        advancedSearch={advancedSearch}
        defaultValue={poolNamePattern ?? ""}
        onChange={handleSearchChange}
        placeholder={translate("pools.searchPlaceholder")}
      />
      <HStack gap={4} mt={4}>
        <Select.Root
          borderWidth={0}
          collection={poolSortOptions}
          defaultValue={["name"]}
          onValueChange={handleSortChange}
          width={130}
        >
          <Select.Trigger>
            <Select.ValueText placeholder={translate("pools.sort.placeholder")} />
          </Select.Trigger>

          <Select.Content>
            {poolSortOptions.items.map((option) => (
              <Select.Item item={option} key={option.value}>
                {option.label}
              </Select.Item>
            ))}
          </Select.Content>
        </Select.Root>
        <Spacer />
        <AddPoolButton />
      </HStack>
      <Box mt={4}>
        <DataTable
          cardDef={cardDef()}
          columns={[]}
          data={data ? data.pools : []}
          displayMode="card"
          initialState={tableURLState}
          isLoading={isLoading}
          modelName="admin:pools.pool"
          noRowsMessage={translate("pools.noPoolsFound")}
          onStateChange={setTableURLState}
          total={data ? data.total_entries : 0}
        />
      </Box>
    </>
  );
};
