import { type FC, useState } from 'react';
import { useNavigate } from 'react-router';

import { IconArrowBigLeftLines, IconPlus } from '@material-hu/icons/tabler';
import Divider from '@material-hu/mui/Divider/Divider';
import IconButton from '@material-hu/mui/IconButton/IconButton';
import { useTheme } from '@material-hu/mui/index';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import StateCard from '@material-hu/components/design-system/StateCard';
import {
  useDialogLayer,
  useDialogLayerItem,
} from '@material-hu/components/layers/Dialogs';

import { type ViewListItem } from 'src/pages/dashboard/serviceManagement/types';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { InfiniteList } from 'src/components/list';

import useViewBubbles from '../../hooks/useViewBubbles';
import useViews from '../../hooks/useViews';
import { serviceManagementRoutes } from '../../routes';
import useViewInputNameModal from '../hooks/useViewInputNameModal';

import CreateViewDrawer from './CreateViewDrawer';
import ViewList from './Views/ViewList';
import ViewListSkeleton from './Views/ViewListSkeleton';

const CONFIRM_DELETE_VIEW_DIALOG_ID = 'confirm-delete-view';

type Props = {
  viewId?: string;
  onSelectBaseView: () => void;
  onSelectView: (id: string) => void;
  isCollapsed: boolean;
  onToggleCollapse: () => void;
};

const ViewSidebar: FC<Props> = ({
  viewId,
  onSelectBaseView,
  onSelectView,
  isCollapsed,
  onToggleCollapse,
}) => {
  const { t } = useLokaliseTranslation('service_management');
  const theme = useTheme();
  const navigate = useNavigate();

  const [viewToAction, setViewToAction] = useState<ViewListItem | null>(null);
  const [createViewDrawerOpen, setCreateViewDrawerOpen] = useState(false);

  const {
    viewsQuery,
    deleteViewMutation,
    renameViewMutation,
    reorderViewMutation,
  } = useViews(viewId);

  const confirmRename = (newName: string) => {
    if (!newName.trim()) return;
    if (viewToAction) {
      renameViewMutation.mutate(
        {
          id: viewToAction.id,
          name: newName,
        },
        {
          onSuccess: handleCloseRenameModal,
        },
      );
    }
  };

  const {
    openInputNameModal: openRenameViewModal,
    closeInputNameModal: closeRenameViewModal,
  } = useViewInputNameModal({
    title: t('rename_view'),
    currentName: viewToAction?.name ?? '',
    loading: renameViewMutation.isLoading,
    onApply: confirmRename,
    onClose: () => closeRenameViewModal(),
    primaryButtonProps: {
      variant: 'primary',
      children: t('rename'),
    },
    secondaryButtonProps: {
      variant: 'text',
      children: t('cancel'),
    },
  });

  const views = viewsQuery.data?.pages.flatMap(page => page.data.items) ?? [];
  const viewsWithBubble = useViewBubbles(views, viewId);
  const totalPages =
    viewsQuery?.data?.pages[viewsQuery?.data?.pages.length - 1]?.data
      ?.totalPages;

  const handleRename = (view: ViewListItem) => {
    setViewToAction(view);
    openRenameViewModal();
  };

  const { closeDialog } = useDialogLayer();

  const closeConfirmDeleteModal = () =>
    closeDialog(CONFIRM_DELETE_VIEW_DIALOG_ID);

  const handleDelete = (view: ViewListItem) => {
    setViewToAction(view);
    openConfirmDeleteModal();
  };

  const confirmDelete = async () => {
    if (viewToAction) {
      await deleteViewMutation.mutateAsync(viewToAction);
      closeConfirmDeleteModal();
      setViewToAction(null);

      if (viewId === viewToAction.id) {
        // If the deleted view is the current view, navigate to the first view in the list
        // or to the default view if there are no views left
        const remainingViews = views.filter(
          view => view.id !== viewToAction.id,
        );

        if (remainingViews.length === 0) {
          onSelectBaseView();
        } else {
          const deletedViewIndex = views.findIndex(
            view => view.id === viewToAction.id,
          );
          if (deletedViewIndex > -1 && deletedViewIndex + 1 < views.length) {
            navigate(
              serviceManagementRoutes.agentSide.viewDetail(
                views[deletedViewIndex + 1].id,
              ),
            );
          } else {
            navigate(
              serviceManagementRoutes.agentSide.viewDetail(
                remainingViews[0].id,
              ),
            );
          }
        }
      }
    }
  };

  const handleSelectView = (id: string) => {
    if (id === viewId) {
      return;
    }
    onSelectView(id);
  };

  const handleReorderView = async (id: string, destinationIdx: number) => {
    await reorderViewMutation.mutateAsync({ id, order: destinationIdx });
  };

  const closeCreateViewDrawer = () => setCreateViewDrawerOpen(false);
  const openCreateViewDrawer = () => setCreateViewDrawerOpen(true);

  const handleCloseRenameModal = () => {
    closeRenameViewModal();
    setViewToAction(null);
  };

  const { openDialog: openConfirmDeleteModal } = useDialogLayerItem(
    CONFIRM_DELETE_VIEW_DIALOG_ID,
    {
      title: t('confirm_delete_view_title'),
      textBody: t('confirm_delete_view_description'),
      primaryButtonProps: {
        color: 'primary',
        children: t('delete_view'),
        onClick: confirmDelete,
        loading: deleteViewMutation.isLoading,
      },
      secondaryButtonProps: {
        color: 'primary',
        children: t('cancel'),
        onClick: closeConfirmDeleteModal,
      },
      onClose: () => {
        closeConfirmDeleteModal();
        setViewToAction(null);
      },
      dialogProps: { fullWidth: true },
    },
  );

  const isBaseViewSelected = !viewId;
  const showEmptyViews = views?.length === 0 && !viewsQuery.isLoading;

  if (isCollapsed) {
    return (
      <Stack
        sx={{
          height: 1,
          px: 2,
          py: 3,
          gap: 2,
          alignItems: 'center',
          backgroundColor: ({ palette }) =>
            palette.new.background.layout.tertiary,
        }}
      >
        <IconButton
          onClick={onToggleCollapse}
          variant="secondary"
          sx={{
            transform: 'rotate(180deg)',
            transition: 'transform 0.2s ease-in-out',
          }}
        >
          <IconArrowBigLeftLines />
        </IconButton>
        <Typography
          variant="globalM"
          fontWeight="fontWeightSemiBold"
          sx={{
            writingMode: 'sideways-lr',
            textOrientation: 'mixed',
          }}
        >
          {t('views')}
        </Typography>
      </Stack>
    );
  }

  return (
    <Stack
      sx={{
        height: 1,
        px: 2,
        py: 3,
        gap: 1.5,
        overflowY: 'auto',
        overflowX: 'hidden',
        backgroundColor: ({ palette }) =>
          palette.new.background.layout.tertiary,
      }}
    >
      <CreateViewDrawer
        open={createViewDrawerOpen}
        onClose={closeCreateViewDrawer}
        viewId={viewId}
      />
      <Stack
        sx={{
          gap: 1,
          px: 0.5,
          pt: 0.5,
          pb: 1.5,
          flexDirection: 'row',
          justifyContent: 'space-between',
          alignItems: 'center',
        }}
      >
        <Stack sx={{ flexDirection: 'row', alignItems: 'center', gap: 1 }}>
          <IconButton
            onClick={onToggleCollapse}
            variant="secondary"
          >
            <IconArrowBigLeftLines />
          </IconButton>
          <Typography
            variant="globalM"
            fontWeight="fontWeightSemiBold"
          >
            {t('views')}
          </Typography>
        </Stack>
        <IconButton onClick={openCreateViewDrawer}>
          <IconPlus />
        </IconButton>
      </Stack>
      <Stack
        onClick={onSelectBaseView}
        sx={{
          py: 1.5,
          pl: 5,
          pr: 1,
          cursor: 'pointer',
          flexDirection: 'row',
          alignItems: 'center',
          backgroundColor: ({ palette }) =>
            isBaseViewSelected
              ? palette.new.action.button.background.tertiary.focus
              : 'transparent',
          '&:hover': {
            backgroundColor: isBaseViewSelected
              ? theme.palette.new.action.button.background.tertiary.focus
              : theme.palette.new.action.button.background.tertiary.hover,
          },
          borderRadius: ({ shape }) => shape.borderRadiusL,
          transition: 'background-color 400ms ease-out',
        }}
      >
        <Typography
          variant="globalS"
          sx={{
            fontWeight: 'fontWeightSemiBold',
            color: ({ palette }) =>
              isBaseViewSelected
                ? palette.new.text.neutral.default
                : palette.new.text.neutral.lighter,
          }}
        >
          {t('all')}
        </Typography>
      </Stack>
      <Divider />
      {viewsQuery.isLoading && <ViewListSkeleton />}
      {showEmptyViews && (
        <StateCard
          title={t('no_views_title')}
          description={t('no_views_description')}
          primaryAction={{
            label: t('create_view'),
            onClick: openCreateViewDrawer,
          }}
          slotProps={{
            card: {
              sx: {
                backgroundColor: ({ palette }) =>
                  palette.new.background.layout.default,
              },
            },
          }}
        />
      )}
      {!showEmptyViews && (
        <InfiniteList
          isLoading={viewsQuery.isLoading}
          fetchNextPage={viewsQuery.fetchNextPage}
          isFetchingNextPage={viewsQuery.isFetchingNextPage}
          totalPages={totalPages ?? 0}
          isSuccess={!!views.length}
          isEmpty={!views.length}
          hasNextPage={!!viewsQuery.hasNextPage}
          sx={{ overflowX: 'hidden' }}
        >
          <ViewList
            onRename={handleRename}
            onDelete={handleDelete}
            selectedViewId={viewId}
            viewsWithBubble={viewsWithBubble}
            views={views}
            onSelect={handleSelectView}
            onReorderView={handleReorderView}
          />
        </InfiniteList>
      )}
    </Stack>
  );
};

export default ViewSidebar;
