import React, {useState, useRef} from 'react';
import {
  Keyboard,
  Pressable,
  ScrollView,
  View,
} from 'react-native';
import {ScreenParams} from '../../navigation/app';
import {
  Colors,
  fontSz,
  globalStyles,
  ms,
  SavingsCategoryType,
  SuggestedPlansOptionsType,
  correctFloatPoint,
  Images,
  formatAsCurrency,
} from '../../utils';
import useHandleChange from '../../hooks/useHandleChangeNotrim';
import Input from '../Input';
import {Text} from '../Text';
import {useSDKConfig} from '../../contexts/SDKConfigContext';
import {useMutation, useQueryClient, useQuery} from '@tanstack/react-query';
import {createSavingsAccount, updateSavingsAccount, getWalletBalance, getLockedSavingsInterestRateTiers} from '../../services/actions';
import {CreateSavingsParams, UpdateSavingsParams} from '../../services/types';
import {useToast} from '../../contexts/ToastProvider';
import Notification from '../Feedback/Notification';
import SavingsConfirmation from '../Modals/savingsConfirmation';
import {SavingsDetailType, LockedSavingsInterestRateTierType} from '../../utils/types';
import SavingsFormLayout from './shared/SavingsFormLayout';
import CommonSavingsFields from './shared/CommonSavingsFields';
import InterestRateTiers from '../Common/InterestRateTiers';
import {
  validateCommonFields,
  validateLockedSavings,
  getValidSavingsColor,
  checkForChanges,
  ValidationError,
} from './shared/savingsFormUtils';
import {SwitchFormInput} from './saveAsYouCollectForm';

type Props = {
  title: string;
  goBack: () => void;
  navigate: <T extends keyof ScreenParams>(
    name: T,
    params?: ScreenParams[T],
  ) => void;
  replace: <T extends keyof ScreenParams>(
    name: T,
    params?: ScreenParams[T],
  ) => void;
  savingsOption: SavingsCategoryType;
  suggestedPlan?: SuggestedPlansOptionsType | null;
  editMode?: boolean;
  existingSavingsData?: SavingsDetailType;
};

const LockedSavingsForm = (props: Props) => {
  const {
    title,
    goBack,
    navigate,
    replace,
    savingsOption,
    suggestedPlan,
    editMode,
    existingSavingsData,
  } = props;

  const minimumLockDuration = savingsOption?.minimumLockDuration || 3;
  const minimumLockDurationDays = minimumLockDuration * 30; // Convert months to days for minimum

  const [switchInterest, setSwitchInterest] = useState<boolean>(
    editMode ? existingSavingsData?.isInterestDisabled || false : false,
  );
  const [lockDurationDays, setLockDurationDays] = useState<number>(0);
  const [currentInterestRate, setCurrentInterestRate] = useState<number>(savingsOption?.interestRate || 0);
  const [selectedTier, setSelectedTier] = useState<LockedSavingsInterestRateTierType | null>(null);


  const {showToast} = useToast();
  const {apiKey, primaryColor} = useSDKConfig();
  const queryClient = useQueryClient();
  const [formStatus, setFormStatus] = useState<
    'idle' | 'loading' | 'success' | 'error'
  >('idle');
  const [showConfirmation, setShowConfirmation] = useState<boolean>(false);
  const [confirmationPayload, setConfirmationPayload] = useState<CreateSavingsParams | UpdateSavingsParams | null>(null);

  // Query for wallet balance
  const {data: walletBalanceData, isLoading: isLoadingBalance} = useQuery({
    queryKey: ['walletBalance', apiKey],
    queryFn: () => getWalletBalance(apiKey),
    retry: 2,
    enabled: !!apiKey,
  });

  // Query for interest rate tiers
  const {data: interestRateTiersData, isLoading: isLoadingTiers} = useQuery({
    queryKey: ['lockedSavingsInterestRateTiers', apiKey],
    queryFn: () => getLockedSavingsInterestRateTiers(apiKey),
    retry: 2,
    enabled: !!apiKey,
  });

  // Ref for scrolling and state for tracking section positions
  const scrollViewRef = useRef<ScrollView>(null);
  const [sectionPositions, setSectionPositions] = useState<{
    [key: string]: number;
  }>({});

  const [errors, setErrors] = useHandleChange({
    name: '',
    amount: '',
    narration: '',
    savingsColor: '',
    lockDurationDays: '',
    tierSelection: '',
  });

  const [details, setDetails] = useHandleChange({
    name: editMode
      ? existingSavingsData?.accountName || ''
      : '',
    amount: editMode ? existingSavingsData?.savingTarget?.toString() || '' : '',
    narration: editMode ? existingSavingsData?.narration || '' : '',
    savingsColor: getValidSavingsColor(
      existingSavingsData?.savingsPlanColor,
      editMode
    ),
  });

  const {name, amount, narration, savingsColor} = details;

  // Get wallet balance values
  const useableWalletBalance = Number(walletBalanceData?.data?.availableBalance ?? 0);
  const lockAmountValue = Number(amount);

  // Get interest rate tiers
  const interestRateTiers: LockedSavingsInterestRateTierType[] = interestRateTiersData || [];

  // Function to calculate current interest rate based on selected days
  const calculateCurrentInterestRate = (days: number): number => {
    if (!interestRateTiers.length) return savingsOption?.interestRate || 0;
    
    const matchingTier = interestRateTiers.find(tier => 
      days >= tier.minDays && days <= tier.maxDays && tier.isActive
    );
    
    return matchingTier ? matchingTier.interestRate : savingsOption?.interestRate || 0;
  };

  // Update interest rate when days change
  React.useEffect(() => {
    if (lockDurationDays > 0) {
      const newRate = calculateCurrentInterestRate(lockDurationDays);
      setCurrentInterestRate(newRate);
    }
  }, [lockDurationDays, interestRateTiers]);

  // Handle tier selection from InterestRateTiers component
  const handleTierSelection = (tier: LockedSavingsInterestRateTierType, isManualSelection: boolean = true) => {
    setSelectedTier(tier);
    setErrors('tierSelection', '');
    // Only reset lock duration when manually selecting from dropdown
    // Don't reset when auto-selecting based on entered days
    if (isManualSelection && (lockDurationDays === 0 || lockDurationDays < tier.minDays || lockDurationDays > tier.maxDays)) {
      setLockDurationDays(0);
      setErrors('lockDurationDays', '');
    }
  };

  function updateSavingsColor(value: string) {
    setDetails('savingsColor', value);
    setErrors('savingsColor', '');
  }
  function updateName(value: string) {
    setDetails('name', value);
    setErrors('name', '');
  }
  function updateAmount(value: number) {
    setDetails('amount', value);
    setErrors('amount', '');

    // Validate against wallet balance
    if (value > useableWalletBalance) {
      setErrors('amount', `Your balance is ${formatAsCurrency(useableWalletBalance)}`);
    } else {
      setErrors('amount', '');
    }
  }
  function updateNarration(value: string) {
    setDetails('narration', value);
    setErrors('narration', '');
  }

  // Helper function to capture section positions
  const handleSectionLayout = (sectionKey: string, event: any) => {
    const {y} = event.nativeEvent.layout;
    setSectionPositions(prev => ({
      ...prev,
      [sectionKey]: y,
    }));
  };

  // Helper function to scroll to first error
  const scrollToError = (errorField: string) => {
    const targetPosition = sectionPositions[errorField];

    if (targetPosition !== undefined && scrollViewRef.current) {
      scrollViewRef.current.scrollTo({
        y: Math.max(0, targetPosition - 50),
        animated: true,
      });
    }
  };

  // Validation function
  const validateForm = (): ValidationError[] => {
    const commonErrors = validateCommonFields(name, amount, savingsColor);
    
    // Calculate maximum days from all tiers
    const maxDaysAvailable = interestRateTiers.length > 0 
      ? Math.max(...interestRateTiers.map(tier => tier.maxDays))
      : 365;
    
    const lockedErrors = validateLockedSavings(
      lockDurationDays,
      minimumLockDurationDays,
      editMode,
      selectedTier,
      maxDaysAvailable
    );

    // Add wallet balance validation
    if (!editMode && lockAmountValue > useableWalletBalance) {
      commonErrors.push({
        field: 'amount',
        message: `Insufficient balance. Maximum amount is ${formatAsCurrency(useableWalletBalance)}`,
      });
    }

    return [...commonErrors, ...lockedErrors];
  };

  const {
    mutate: savingsMutate,
    isPending: isLoading,
    data,
  } = useMutation({
    mutationFn: (variables: CreateSavingsParams | UpdateSavingsParams) => {
      if (editMode) {
        return updateSavingsAccount(apiKey, variables as UpdateSavingsParams);
      } else {
        return createSavingsAccount(apiKey, variables as CreateSavingsParams);
      }
    },
    onSuccess: res => {
      if (res.error) {
        showToast({
          type: 'error',
          message:
            res?.error ??
            `An error occurred while ${editMode ? 'updating' : 'creating'} your savings account. Please try again.`,
          duration: 3000,
        });
        return;
      }
      if (res?.success) {
        // Invalidate relevant queries to fetch latest data
        queryClient.invalidateQueries({
          queryKey: ['savingsListByCustomerId', apiKey],
        });
        queryClient.invalidateQueries({
          queryKey: ['totalAccountTransactionsByCustomerId', apiKey],
        });
        queryClient.invalidateQueries({
          queryKey: ['customerAccountSummary', apiKey],
        });
        queryClient.invalidateQueries({
          queryKey: ['allSavingsCategories', apiKey],
        });

        // Close the confirmation modal and clear payload
        setShowConfirmation(false);
        setConfirmationPayload(null);
        setFormStatus('success');
      }
    },
    onError: err => {
      console.error('Mutation failed:', err);
    },
  });

  function onSuccessNotificationClose() {
    setFormStatus('idle');

    replace('plan', {
      planId: data?.responseData.savingsId,
      planName: data?.responseData.accountName,
    });
  }

  const handleSubmit = async () => {
    Keyboard.dismiss();

    // Validate form and get all errors
    const validationErrors = validateForm();

    if (validationErrors.length > 0) {
      // Set all errors
      validationErrors.forEach(({field, message}) => {
        setErrors(field, message);
      });

      // Scroll to first error after a brief delay to allow error state to update
      setTimeout(() => {
        scrollToError(validationErrors[0].field);
      }, 100);

      return;
    }

    // Form is valid, proceed with submission
    let payload: CreateSavingsParams | UpdateSavingsParams;

    if (editMode) {
      payload = {
        savingsId: existingSavingsData?.savingsId || '',
        planId: suggestedPlan?.id ?? 0,
        accountName: name.trim(),
        savingTarget: correctFloatPoint(Number(amount) * 100),
        savingsCategoryId: savingsOption.id,
        narration: narration.trim(),
        autoSave: false, // Always false for locked savings
        isInterestDisabled: switchInterest,
        savingsPlanColor: savingsColor,
      } as UpdateSavingsParams;
    } else {
      // Calculate end date based on lock duration in days
      const startDate = new Date();
      const endDate = new Date(startDate);
      endDate.setDate(endDate.getDate() + lockDurationDays);

      payload = {
        planId: suggestedPlan?.id ?? 0,
        accountName: name.trim(),
        savingTarget: correctFloatPoint(Number(amount) * 100),
        savingsCategoryId: savingsOption.id,
        narration: narration.trim(),
        autoSave: false, // Always false for locked savings
        isInterestDisabled: switchInterest,
        savingsPlanColor: savingsColor,
        startDate: startDate.toISOString(),
        endDate: endDate.toISOString(),
      } as CreateSavingsParams;
    }

    if (suggestedPlan?.name === name) {
      payload.planId = suggestedPlan?.id;
    }

    // In edit mode, check if there are any actual changes
    if (editMode && existingSavingsData) {
      const hasChanges = checkForChanges(payload as UpdateSavingsParams, existingSavingsData);

      if (!hasChanges) {
        // No changes detected, show a toast and return
        showToast({
          type: 'info',
          message: 'No changes detected. Your savings account is already up to date.',
          duration: 3000,
        });
        return;
      }
    }

    // Show confirmation modal instead of directly submitting
    setConfirmationPayload(payload);
    setShowConfirmation(true);
  };

  const handleConfirmSubmission = async () => {
    if (confirmationPayload) {
      savingsMutate(confirmationPayload);
    }
  };

  const handleCancelConfirmation = () => {
    setShowConfirmation(false);
    setConfirmationPayload(null);
  };

  return (
    <>
      <SavingsFormLayout
        title={title}
        onBack={goBack}
        onSubmit={handleSubmit}
        scrollViewRef={scrollViewRef}
        suggestedPlanName={suggestedPlan?.name}>

        <CommonSavingsFields
          savingsColor={savingsColor}
          onColorChange={updateSavingsColor}
          colorError={errors.savingsColor}
          primaryColor={primaryColor}
          name={name}
          onNameChange={updateName}
          nameError={errors.name}
          amount={amount}
          onAmountChange={updateAmount}
          amountError={errors.amount}
          amountLabel="Lock Amount"
          showAmountField={true}
          walletBalance={useableWalletBalance}
          showBalance={true}
          isLoadingBalance={isLoadingBalance}
          onColorLayout={event => handleSectionLayout('savingsColor', event)}
          onNameLayout={event => handleSectionLayout('name', event)}
          onAmountLayout={event => handleSectionLayout('amount', event)}
        />

        <InterestRateTiers
          tiers={interestRateTiers}
          selectedDays={lockDurationDays}
          currentRate={switchInterest ? 0 : currentInterestRate}
          onTierSelect={handleTierSelection}
          onDaysChange={(days: number) => {
            setLockDurationDays(days);
            setErrors('lockDurationDays', '');
          }}
          primaryColor={primaryColor}
          isLoading={isLoadingTiers}
          minimumLockDurationDays={minimumLockDurationDays}
          durationError={errors.lockDurationDays}
          tierSelectionError={errors.tierSelection}
          onSectionLayout={event => handleSectionLayout('lockDurationDays', event)}
          lockAmount={lockAmountValue}
          isInterestDisabled={switchInterest}
          selectedTier={selectedTier}
        />

        {/* Narration - positioned after Locked Savings specific fields */}
        <Input
          value={narration}
          label="Narration"
          placeholder="Describe"
          keyboardType="default"
          autoCompleteType="off"
          returnKeyType="done"
          onChange={(value: React.SetStateAction<string>) => {
            updateNarration(String(value));
          }}
          errorMsg={errors.narration || ''}
          onEndEditing={() => {}}
          onFocus={() => {}}
          containerStyle={{marginTop: ms(-24)}}
        />

        <SwitchFormInput
          title="Switch off Interest"
          onPress={() => setSwitchInterest(!switchInterest)}
          onValueChange={() => setSwitchInterest(!switchInterest)}
          check={switchInterest}
          setCheck={setSwitchInterest}
        />
      </SavingsFormLayout>

      {formStatus === 'success' && (
        <Notification
          title={editMode ? 'Savings Updated Successfully' : 'Savings Created Successfully'}
          description={editMode ? 'Your savings account has been updated successfully' : 'Your savings account has been created successfully'}
          image={Images.successIcon}
          buttonText="View Details"
          onButtonPress={onSuccessNotificationClose}
        />
      )}

      {confirmationPayload && (
        <SavingsConfirmation
          visible={showConfirmation}
          editMode={editMode || false}
          newData={confirmationPayload}
          existingData={existingSavingsData}
          onConfirm={handleConfirmSubmission}
          onCancel={handleCancelConfirmation}
          isLoading={isLoading}
          savingsCategoryName={savingsOption.name}
          isLockedCategory={true}
        />
      )}
    </>
  );
};

export default LockedSavingsForm;
