import React, {useCallback, useState} from 'react';
import {Keyboard, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {IconCheck, IconCircleX} from '@tabler/icons-react-native';
import {useMutation, useQueryClient} from '@tanstack/react-query';
import {FormProvider, useForm} from 'react-hook-form';
import {zodResolver} from '@hookform/resolvers/zod';
import {z} from 'zod';
import {
  Button,
  Dialog,
  INPUT_STYLES,
  InputClassicController,
} from '@components';
import {TEXT_AREA_MIN_HEIGHT} from '@components/_HuGo/Inputs/constants';
import {
  AmplitudeServiceManagementRole,
  AmplitudeServiceManagementSource,
  ApprovalGroupStatus,
} from '@modules/serviceManagement/interfaces';
import {useApprovalsGetStates} from '@modules/serviceManagement/hooks/useApprovalsGetStates';
import {changeTaskState} from '@modules/serviceManagement/services';
import {invalidateApprovalTasksQueries} from '@modules/serviceManagement/utils';
import {showSnackbar} from '@redux/dispatchers';
import {useAppSelector} from '@redux/utils';
import {requiredString} from '@shared/schemas';
import {logAmplitudeEvent} from '@shared/utils';
import {AMPLITUDE_EVENTS} from '@shared/constants';

import {styles} from './styles';

interface ApprovalTaskActionsProps {
  taskId: string;
  approvalGroupId?: string;
  parentTaskId: string;
  parentTaskName: string;
  source: AmplitudeServiceManagementSource;
}

type ActionType = 'reject' | 'approve';

function ApprovalTaskActions({
  taskId,
  approvalGroupId,
  parentTaskId,
  parentTaskName,
  source,
}: ApprovalTaskActionsProps) {
  const queryClient = useQueryClient();
  const isAgent = useAppSelector(({user}) => user.isAgent);
  const {t} = useTranslation();
  const [visibleDialog, setVisibleDialog] =
    useState<Nullable<ActionType>>(null);
  const {states, isLoadingStates} = useApprovalsGetStates();
  const methods = useForm<{message: string}>({
    resolver: zodResolver(
      z.object({
        message: visibleDialog === 'reject' ? requiredString() : z.string(),
      }),
    ),
    defaultValues: {
      message: '',
    },
  });
  const {
    handleSubmit,
    reset,
    formState: {isValid, isDirty},
  } = methods;

  const onCloseDialog = useCallback(() => {
    setVisibleDialog(null);
    reset();
  }, [reset]);

  const onOpenApprovalDialog = useCallback(() => {
    setVisibleDialog('approve');
    reset();
  }, [reset]);

  const onOpenRejectionDialog = useCallback(() => {
    setVisibleDialog('reject');
    reset();
  }, [reset]);

  const {mutate: onChangeState, isPending: isPendingChangeState} = useMutation({
    mutationFn: ({action, message}: {action: ActionType; message: string}) => {
      Keyboard.dismiss();
      if (
        !states ||
        !states[ApprovalGroupStatus.Approved].id ||
        !states[ApprovalGroupStatus.Rejected].id
      ) {
        showSnackbar({
          title: t('errors.api.500', {info: ''}),
          variant: 'error',
        });
        return Promise.reject(new Error('Invalid states'));
      }

      return changeTaskState({
        taskId,
        stateId:
          action === 'approve'
            ? states[ApprovalGroupStatus.Approved].id
            : states[ApprovalGroupStatus.Rejected].id,
        message: message || undefined,
      });
    },
    onSuccess: () => {
      logAmplitudeEvent(AMPLITUDE_EVENTS.SERVICE_MGMT_APPROVAL_ACTION_TAKEN, {
        serviceId: parentTaskId,
        serviceName: parentTaskName,
        approval_step_id: taskId,
        approval_action_type:
          visibleDialog === 'approve' ? 'APPROVED' : 'REJECTED',
        screen_source: source,
        approver_role: isAgent
          ? AmplitudeServiceManagementRole.AGENT
          : AmplitudeServiceManagementRole.APPROVER,
      });

      invalidateApprovalTasksQueries(queryClient, {
        parentTaskId,
        approvalGroupId,
      });

      onCloseDialog();
    },
    onError: onCloseDialog,
  });

  const onSubmit = useCallback(
    (data: {message: string}) => {
      if (visibleDialog) {
        onChangeState({action: visibleDialog, message: data.message});
      }
    },
    [onChangeState, visibleDialog],
  );

  return (
    <>
      <View style={styles.buttonsContainer}>
        <Button
          text={t('service_management.approvals.reject')}
          IconLeft={IconCircleX}
          variant="secondary"
          containerStyle={styles.button}
          size="sm"
          onPress={onOpenRejectionDialog}
        />
        <Button
          text={t('service_management.approvals.approve')}
          IconLeft={IconCheck}
          containerStyle={styles.button}
          size="sm"
          onPress={onOpenApprovalDialog}
        />
      </View>
      <Dialog
        title={t('service_management.approvals.message')}
        isVisible={!!visibleDialog}
        onClose={onCloseDialog}
        footer={{
          primaryButton: {
            text: t(
              visibleDialog === 'approve'
                ? 'service_management.approvals.approve'
                : 'service_management.approvals.reject',
            ),
            onPress: () => visibleDialog && handleSubmit(onSubmit)(),
            disabled: isLoadingStates || (!isValid && isDirty),
            isLoading: isPendingChangeState,
          },
        }}>
        <FormProvider {...methods}>
          <View>
            <InputClassicController
              name="message"
              multiline
              useBottomSheetTextInput
              size="lg"
              style={[
                INPUT_STYLES.longInputSpacing,
                {height: TEXT_AREA_MIN_HEIGHT, maxHeight: TEXT_AREA_MIN_HEIGHT},
              ]}
            />
          </View>
        </FormProvider>
      </Dialog>
    </>
  );
}

export default ApprovalTaskActions;
