/*!
 * 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, Flex, Heading, HStack, Skeleton, Text } from "@chakra-ui/react";
import { useTranslation } from "react-i18next";
import { BiTargetLock } from "react-icons/bi";

import { type PoolServiceGetPoolsDefaultResponse, useAuthLinksServiceGetAuthMenus } from "openapi/queries";
import { usePoolServiceGetPools } from "openapi/queries/queries";
import type { ApiError } from "openapi/requests";
import { PoolBar, UNLIMITED_SLOTS } from "src/components/PoolBar";
import { StateIcon } from "src/components/StateIcon";
import { RouterLink, Tooltip } from "src/components/ui";
import { useAutoRefresh } from "src/utils";
import { type Slots, slotKeys } from "src/utils/slots";

export const PoolSummary = () => {
  const { t: translate } = useTranslation("dashboard");
  const refetchInterval = useAutoRefresh({ checkPendingRuns: true });

  const { data: authLinks } = useAuthLinksServiceGetAuthMenus();
  const hasPoolsAccess = authLinks?.authorized_menu_items.includes("Pools");

  const { data, error, isLoading } = usePoolServiceGetPools<PoolServiceGetPoolsDefaultResponse, ApiError>(
    undefined,
    undefined,
    {
      refetchInterval: (query) => {
        const apiError = query.state.error;

        return apiError?.status === 403 ? false : refetchInterval;
      },
    },
  );

  if (error?.status === 403) {
    return undefined;
  }

  const pools = data?.pools;
  const hasUnlimitedPool = pools?.some((pool) => pool.slots === UNLIMITED_SLOTS) ?? false;
  const totalSlots = hasUnlimitedPool
    ? UNLIMITED_SLOTS
    : (pools?.reduce((sum, pool) => sum + pool.slots, 0) ?? 0);
  const aggregatePool: Slots = {
    deferred_slots: 0,
    open_slots: 0,
    queued_slots: 0,
    running_slots: 0,
    scheduled_slots: 0,
  };

  const poolsWithSlotType: Slots = {
    deferred_slots: 0,
    open_slots: 0,
    queued_slots: 0,
    running_slots: 0,
    scheduled_slots: 0,
  };
  let deferredSlotsNotCounted = 0;

  pools?.forEach((pool) => {
    slotKeys.forEach((slotKey) => {
      if (slotKey === "deferred_slots" && !pool.include_deferred) {
        deferredSlotsNotCounted += pool.deferred_slots;

        return;
      }

      const slotValue = pool[slotKey];

      if (slotValue === UNLIMITED_SLOTS) {
        aggregatePool[slotKey] = UNLIMITED_SLOTS;
        poolsWithSlotType[slotKey] += 1;
      } else if (slotValue > 0) {
        if (aggregatePool[slotKey] !== UNLIMITED_SLOTS) {
          aggregatePool[slotKey] += slotValue;
        }
        poolsWithSlotType[slotKey] += 1;
      }
    });
  });

  return (
    <Box w="100%">
      <Flex color="fg.muted" justifyContent="space-between" mb={2} w="100%">
        <Flex alignItems="center">
          <BiTargetLock />
          <Heading ml={1} size="xs">
            {translate("poolSlots")}
          </Heading>
        </Flex>
        {hasPoolsAccess ? (
          <RouterLink fontSize="xs" h={4} to="/pools">
            {translate("managePools")}
          </RouterLink>
        ) : undefined}
      </Flex>

      {isLoading ? (
        <Skeleton borderRadius="full" h={8} w="100%" />
      ) : (
        <>
          <PoolBar pool={aggregatePool} poolsWithSlotType={poolsWithSlotType} totalSlots={totalSlots} />
          {deferredSlotsNotCounted > 0 ? (
            <Tooltip content={translate("deferredSlotsNotCountedTooltip")}>
              <HStack gap={1} mt={1} w="fit-content">
                <StateIcon size={12} state="deferred" />
                <Text color="fg.muted" fontSize="xs" fontWeight="medium">
                  {translate("deferredSlotsNotCounted", { count: deferredSlotsNotCounted })}
                </Text>
              </HStack>
            </Tooltip>
          ) : undefined}
        </>
      )}
    </Box>
  );
};
