import { Suspense, useEffect, useMemo, useState } from 'react';
import {
  FormProvider,
  type UseFormReturn,
  useForm,
  useFormContext,
} from 'react-hook-form';

import { IconHelp, IconPlus } from '@material-hu/icons/tabler';
import Skeleton from '@material-hu/mui/Skeleton';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuMenuList from '@material-hu/components/composed-components/MenuList';
import HuAccordion from '@material-hu/components/design-system/Accordion';
import HuAvatar from '@material-hu/components/design-system/Avatar';
import Button from '@material-hu/components/design-system/Buttons/Button';
import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import HuFormInputClassic from '@material-hu/components/design-system/Inputs/Classic/form';
import HuPills from '@material-hu/components/design-system/Pills';
import HuTooltip from '@material-hu/components/design-system/Tooltip';

import useProfileFields from 'src/hooks/queryHooks/useProfileFields';
import useSegmentationGroups from 'src/hooks/queryHooks/useSegmentationGroups';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import {
  type BranchType,
  type EdgeType,
  type FlowNode,
  type WorkflowForm,
} from 'src/types/workflows';
import { insertIf } from 'src/utils/arrayUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import Condition from 'src/components/Condition';
import {
  defaultConditionValues,
  dynamicPrefix,
  fieldPrefix,
} from 'src/components/Condition/components/constants';
import useConditionData from 'src/components/Condition/utils/useConditionData';

import {
  addBranch,
  getBranchIndex,
  type InvalidNodeInfo,
  isBranchInvalid,
  jsonLogicToConditions,
  nanoid,
  removeBranch,
} from '../../utils';
import EditActions from '../EditActions';

type Props = {
  node?: FlowNode;
  invalidNodes?: InvalidNodeInfo[];
  workflowForm?: UseFormReturn<WorkflowForm>;
};

const DEFAULT = 'default';

const BranchesContent = ({ node, invalidNodes, workflowForm }: Props) => {
  const { t } = useLokaliseTranslation('workflows');
  const HuGoThemeProvider = useHuGoTheme();
  const form = useFormContext();
  const [editingBranchId, setEditingBranchId] = useState<string | null>(null);

  const isEditing = !!node;
  const branches = form.watch('node.branches');
  const branchesLength = branches?.length - 1 || 0;
  const showExpanded = (branch: BranchType, index: number) =>
    (!node && index === 0) ||
    (branchesLength > 0 &&
      index === branchesLength &&
      (Array.isArray(branch.condition)
        ? !branch.condition[0]?.value
        : !branch.condition));

  const defaultBranch = form.watch('node.defaultBranch');
  const workflowBody = workflowForm?.getValues('body');

  const nodeIsInvalid = invalidNodes?.some(n => n.id === node?.id);

  // Check if a branch has connected logic: can't be deleted
  const hasBranchConnectedNodes = (branchEdgeId: string | null): boolean => {
    if (!branchEdgeId || !workflowBody?.edges) return false;

    const branchEdge = workflowBody.edges.find(
      (edge: EdgeType) => edge.id === branchEdgeId,
    );
    if (!branchEdge) return false;

    const isTargetEndNode = workflowBody.end?.some(
      (endNode: { id: string }) => endNode.id === branchEdge.targetId,
    );

    return !isTargetEndNode;
  };

  useEffect(() => {
    if (isEditing) form.setValue('node', node);
    form.setValue(
      'node.branches',
      node?.branches?.map((branch: BranchType) => ({
        ...branch,
        condition:
          typeof branch.condition === 'string'
            ? jsonLogicToConditions(branch.condition)
            : branch.condition,
      })) || [
        {
          edgeId: `edge${nanoid()}`,
          name: `${t('branch')} 1`,
          condition: [defaultConditionValues],
        },
      ],
    );
    form.setValue(
      'node.defaultBranch',
      node?.defaultBranch || {
        edgeId: `edge${nanoid()}`,
        name: t('branches_none'),
        condition: false,
      },
    );
  }, [form.setValue, isEditing, node, t]);

  const handleSave = (branchId: string) => {
    if (!branchId) return;

    if (!branchForm.getValues('name').trim()) {
      setEditingBranchId(null);
      branchForm.setValue('name', '');
      return;
    }

    if (branchId === DEFAULT) {
      form.setValue('node.defaultBranch', {
        ...defaultBranch,
        name: branchForm.getValues('name').trim(),
      });
    } else {
      const updatedBranches = branches?.map((branch: BranchType) =>
        branch.edgeId === branchId
          ? { ...branch, name: branchForm.getValues('name').trim() }
          : branch,
      );

      form.setValue('node.branches', updatedBranches);
    }

    setEditingBranchId(null);
    branchForm.setValue('name', '');
  };

  const handleCancel = (branchId: string) => {
    if (!branchId) return;

    if (branchId === DEFAULT) {
      branchForm.setValue('name', defaultBranch.name);
    } else {
      const branch = branches?.find((b: BranchType) => b.edgeId === branchId);
      if (branch) {
        branchForm.setValue('name', branch.name);
      }
    }

    setEditingBranchId(null);
  };

  const options = (id: string | null) => [
    {
      title: t('rename'),
      onClick: () => {
        const branch = branches?.find((b: BranchType) => b.edgeId === id);
        if (branch) {
          setEditingBranchId(id);
          branchForm.setValue('name', branch.name);
        } else {
          setEditingBranchId(DEFAULT);
          branchForm.setValue('name', defaultBranch.name);
        }
      },
    },
    ...insertIf(!!id, {
      title: t('delete'),
      description:
        branches?.length && hasBranchConnectedNodes(id)
          ? t('delete_branch_disabled')
          : undefined,
      disabled: branches?.length === 1 || hasBranchConnectedNodes(id),
      onClick: () => form.setValue('node.branches', removeBranch(branches, id)),
    }),
  ];

  const handleAddBranch = () => {
    form.setValue(
      'node.branches',
      addBranch(branches, {
        edgeId: 'edge' + nanoid(),
        condition: [defaultConditionValues],
        name: `${t('branch')} ${branches?.length + 1}`,
      }),
    );
  };

  const branchForm = useForm({
    defaultValues: {
      name: '',
      conditions: null,
    },
    mode: 'onChange',
  });

  const { data: profileFields } = useProfileFields({
    select: data =>
      data.data.map(field => ({
        ...field,
        id: `${fieldPrefix}${dynamicPrefix}${field.id}`,
      })),
    keepPreviousData: true,
  });

  const { data: segmentationGroups } = useSegmentationGroups();

  // Get conditions data - watch all form values to catch nested changes
  const formValues = form.watch();
  const nodeConditions = useMemo(() => {
    const nodeBranches = formValues?.node?.branches || [];
    const conditions = nodeBranches.flatMap((branch: BranchType) =>
      Array.isArray(branch.condition) ? branch.condition : [],
    );
    return conditions;
  }, [formValues]);

  const conditionData = useConditionData(nodeConditions, profileFields);

  return (
    <HuGoThemeProvider>
      <Stack sx={{ height: '100%', gap: 2, overflow: 'auto' }}>
        <Typography
          variant="globalS"
          sx={{ fontWeight: 'semiBold' }}
        >
          {t('branches_description')}
        </Typography>
        <FormProvider {...branchForm}>
          {branches?.map((branch: BranchType, index: number) => (
            <Stack key={branch.edgeId}>
              {editingBranchId === branch.edgeId && (
                <Stack
                  sx={{
                    p: 2,
                    flexDirection: 'row',
                    gap: 1,
                    width: 'inherit',
                    alignItems: 'inherit',
                    backgroundColor: theme =>
                      theme.palette.new.background.elements.grey,
                    borderRadius: 2,
                  }}
                >
                  <HuAvatar text={getBranchIndex(index)} />
                  <HuFormInputClassic
                    inputProps={{
                      placeholder: t('branch_name'),
                      hasCounter: false,
                      size: 'small',
                      autoFocus: true,
                      showClear: false,
                      onKeyDown: e =>
                        e.key === 'Enter' && handleSave(branch.edgeId),
                      onBlur: () => handleSave(branch.edgeId),
                    }}
                    name="name"
                  />
                  <EditActions
                    onCancel={() => handleCancel(branch.edgeId)}
                    onSave={() => handleSave(branch.edgeId)}
                  />
                </Stack>
              )}
              {editingBranchId !== branch.edgeId && (
                <HuCardContainer
                  fullWidth
                  padding={0}
                  color="grey"
                  sx={{
                    border: 'none',
                  }}
                  {...(nodeIsInvalid &&
                    isBranchInvalid(branch) && {
                      badge: {
                        label: t('pending_configuration'),
                        type: 'warning',
                        hasIcon: true,
                      },
                    })}
                >
                  <HuAccordion
                    defaultExpanded={
                      showExpanded(branch, index) ||
                      (nodeIsInvalid && isBranchInvalid(branch))
                    }
                    title={branch.name}
                    avatar={{
                      text: getBranchIndex(index),
                    }}
                    menuList={{
                      options: options(branch.edgeId),
                      minWidth: '120px',
                      position: 'right',
                      slotProps: {
                        menu: {
                          sx: { cursor: 'not-allowed' },
                        },
                      },
                    }}
                    customDetail={
                      <FormProvider {...form}>
                        <Condition
                          name={`node.branches[${index}].condition`}
                          profileFields={profileFields || []}
                          conditionData={conditionData}
                          segmentationGroups={segmentationGroups}
                        />
                      </FormProvider>
                    }
                    sx={{
                      backgroundColor: 'transparent',
                      p: 0,
                      '& .MuiTypography-root': {
                        maxWidth: 350,
                        overflow: 'hidden',
                        textOverflow: 'ellipsis',
                        whiteSpace: 'nowrap',
                      },
                    }}
                    elevation={0}
                  />
                </HuCardContainer>
              )}
            </Stack>
          ))}
        </FormProvider>
        <HuTooltip
          title={t('branches_limit')}
          description={t('branches_limit_description')}
          disableTooltip={branches?.length < 9}
        >
          <span>
            <Button
              variant="outlined"
              color="primary"
              startIcon={<IconPlus />}
              onClick={handleAddBranch}
              disabled={branches?.length >= 9}
              fullWidth
            >
              {t('new_branch')}
            </Button>
          </span>
        </HuTooltip>
        {/* Default branch */}
        <FormProvider {...branchForm}>
          <Stack
            sx={{
              p: 2,
              width: '100%',
              borderRadius: 2,
              alignItems: 'center',
              flexDirection: 'row',
              backgroundColor: theme =>
                theme.palette.new.background.elements.grey,
            }}
          >
            <Stack
              sx={{
                flexDirection: 'row',
                gap: 1,
                width: 'inherit',
                alignItems: 'inherit',
              }}
            >
              <HuAvatar text={getBranchIndex(branches?.length)} />
              {editingBranchId === DEFAULT && (
                <>
                  <HuFormInputClassic
                    inputProps={{
                      placeholder: t('branch_name'),
                      hasCounter: false,
                      showClear: false,
                      autoFocus: true,
                      size: 'small',
                      onKeyDown: e => e.key === 'Enter' && handleSave(DEFAULT),
                      onBlur: () => handleSave(DEFAULT),
                    }}
                    name="name"
                  />
                  <EditActions
                    onCancel={() => handleCancel(DEFAULT)}
                    onSave={() => handleSave(DEFAULT)}
                  />
                </>
              )}
              {editingBranchId !== DEFAULT && (
                <>
                  <Typography
                    variant="globalS"
                    sx={{
                      fontWeight: 'semiBold',
                      maxWidth: 250,
                      overflow: 'hidden',
                      textOverflow: 'ellipsis',
                      whiteSpace: 'nowrap',
                    }}
                  >
                    {defaultBranch?.name}
                  </Typography>
                  <HuTooltip
                    description={t('default_branch_tooltip')}
                    direction="bottom"
                  >
                    <IconHelp size={16} />
                  </HuTooltip>
                </>
              )}
            </Stack>
            {editingBranchId !== DEFAULT && (
              <Stack
                sx={{ gap: 1, flexDirection: 'row', alignItems: 'center' }}
              >
                <HuPills
                  label={t('default_branch')}
                  type="highlight"
                  size="small"
                  hasIcon={false}
                />
                <HuMenuList
                  options={options(null)}
                  minWidth="120px"
                  position="right"
                />
              </Stack>
            )}
          </Stack>
        </FormProvider>
      </Stack>
    </HuGoThemeProvider>
  );
};

const BranchesSkeleton = () => (
  <Stack sx={{ height: '100%', gap: 2 }}>
    <Skeleton
      variant="text"
      width="60%"
      height={30}
    />
    <Skeleton
      variant="rounded"
      width="100%"
      height={100}
    />
    <Skeleton
      variant="rounded"
      width="100%"
      height={100}
    />
  </Stack>
);

const Branches = (props: Props) => (
  <Suspense fallback={<BranchesSkeleton />}>
    <BranchesContent {...props} />
  </Suspense>
);

export default Branches;
