'use client';

import React, { useState, useCallback, useEffect } from 'react';
import {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogTitle,
  DialogDescription,
  DialogClose,
} from '@/components/ui/dialog';
import CommonImage from '@/components/common/CommonImage';
import { VisuallyHidden } from '@radix-ui/react-visually-hidden';
import { Control, useForm } from 'react-hook-form';
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { API_ENDPOINTS } from '@/constants';
import {
  ApiResponse,
  BucketProp,
  fnEmpty,
  HandlePaginatedRecords,
  UnknownRecord,
} from '@/types';
import { globalApiGet, globalApiPost } from '@/services/global/globalApiCalls';
import { Button } from '@/components/ui/button';
import { Text } from '../../../ui/text';
import { Input } from '../../../ui/input';
import TaxSection, { FormDataWithTaxDetails } from '../../../common/TaxSection';
import {
  bankAccountDependentPaymentMode,
  calculateAmount,
  prepareEditFormDefaultValues,
} from './constants';
import { DateMode, validateInputDate } from '@/utils/dateValidation';
import { maskDate } from '@/utils/dateMask';
import { SearchableSelect } from '../../contracts/forms/SearchableSelect';
import { Textarea } from '@/components/ui/textarea';
import { useAppToast } from '@/hooks/useAppToast';
import { C_M } from '@/constants/typo/submit-alerts';

export type EditSubAgentBonusProps = {
  triggerIcon?: React.ReactNode;
  bucket: BucketProp['bucket'];
  handlePaginatedRecords: HandlePaginatedRecords;
  record: UnknownRecord;
  onSuccess?: fnEmpty;
};

const EditSubAgentBonus: React.FC<EditSubAgentBonusProps> = ({
  record,
  triggerIcon,
  bucket,
  handlePaginatedRecords,
  onSuccess,
}) => {
  const { showSuccess, showError } = useAppToast();
  const [isOpen, setIsOpen] = useState(false);

  const EditSubAgentBonusSchema = bucket?.crud?.edit.schema.validator;

  const form = useForm<z.infer<typeof EditSubAgentBonusSchema>>({
    resolver: zodResolver(EditSubAgentBonusSchema),
    defaultValues: prepareEditFormDefaultValues(record),
  });

  const {
    handleSubmit,
    control,
    formState: { isSubmitting },
    setValue,
    setError,
    clearErrors,
    getValues,
    reset,
  } = form;

  const [dropdownStates, setDropdownStates] = useState({
    associate_id: false,
    payment_mode_id: false,
    from_bank_account_id: false,
    to_bank_account_id: false,
  });

  const toggleDropdown = useCallback((key: keyof typeof dropdownStates) => {
    setDropdownStates((prev) => ({ ...prev, [key]: !prev[key] }));
  }, []);

  const [defaultAssociates, setDefaultAssociates] = useState<UnknownRecord[]>(
    [],
  );
  const [defaultPaymentModes, setDefaultPaymentModes] = useState<
    UnknownRecord[]
  >([]);
  const [defaultFromBanks, setDefaultFromBanks] = useState<UnknownRecord[]>([]);
  const [defaultToBanks, setDefaultToBanks] = useState<UnknownRecord[]>([]);
  const [totalAmount, setTotalAmount] = useState<number | string>(0);
  const [amountAfterTax, setAmountAfterTax] = useState<string | number>(0);
  const [otherDeduction, setOtherDeduction] = useState<string | number>(0);
  const [netAmount, setNetAmount] = useState<string | number>(0);
  const [paymentMode, setPaymentMode] = useState<number>(0);

  // New helper: loads banks WITHOUT clearing the saved selection
  const loadAssociateBanks = useCallback(async (associateId: string) => {
    try {
      const toBankAccounts = await globalApiPost<ApiResponse<UnknownRecord[]>>(
        API_ENDPOINTS.SUB_AGENT_BONUS.TO_BANK_LIST,
        { associate_id: Number(associateId) },
      );
      setDefaultToBanks(Array.isArray(toBankAccounts) ? toBankAccounts : []);
    } catch (error) {
      console.error('Error loading Associate Bank Account:', error);
      setDefaultToBanks([]);
    }
  }, []);

  // Reset form with current record data when dialog opens or record changes
  const handleFormReset = useCallback(() => {
    const defaultValues = prepareEditFormDefaultValues(record);
    reset(defaultValues);

    setTotalAmount(record.total_amount || 0);
    setOtherDeduction(record.other_deductions || 0);
    setNetAmount(record.net_amount_inr || 0);
    setPaymentMode(record.payment_mode_id || 0);

    if (record.total_amount) {
      // ← Pass the deduction explicitly so it's not read from stale state
      handleTotalAmountOnChange(
        record.total_amount,
        record.other_deductions || 0,
      );
    }

    if (record.associate_id) {
      loadAssociateBanks(String(record.associate_id));
    }
  }, [record, reset, loadAssociateBanks]);

  const handleOpenChange = async (open: boolean) => {
    setIsOpen(open);
    if (open) {
      handleFormReset();
      handleOnOpen();
    }
  };

  // Update form when record changes while dialog is open
  useEffect(() => {
    if (isOpen) {
      handleFormReset();
    }
  }, [record, isOpen, handleFormReset]);

  useEffect(() => {
    setValue('remarks', record.remarks);
    if (
      isOpen &&
      record.tax_details &&
      Array.isArray(record.tax_details) &&
      record.tax_details.length > 0
    ) {
      const initialTaxes = record.tax_details.map((rec, index) => {
        return {
          tax_amount: String(rec.tax_amount || ''),
          tax_name: rec.tax_name || '',
          tax_per: String(rec.tax_per || ''),
        };
      });

      setValue('items', initialTaxes);
      const totalAmountValue = getValues('total_amount');
      if (totalAmountValue) {
        handleTotalAmountOnChange(totalAmountValue);
      }
    } else if (isOpen) {
      setValue('items', []);
    }
  }, [record.tax_details, isOpen, setValue, getValues]);

  const handleOnOpen = useCallback(async () => {
    const extractData = (response: unknown) =>
      Array.isArray(response) ? response : [];

    const apiRequests = [
      globalApiGet(API_ENDPOINTS.SUB_AGENT_BONUS.ASSOCIATE_LIST),
      globalApiGet(API_ENDPOINTS.SUB_AGENT_BONUS.PAYMENT_MODE_LIST),
      globalApiGet(API_ENDPOINTS.SUB_AGENT_BONUS.FROM_BANK_LIST),
    ];

    try {
      const [associatesRes, paymentModesRes, fromBanksRes] = (await Promise.all(
        apiRequests,
      )) as ApiResponse<UnknownRecord>[];

      setDefaultAssociates(extractData(associatesRes));
      setDefaultPaymentModes(extractData(paymentModesRes));
      setDefaultFromBanks(extractData(fromBanksRes));
    } catch (error) {
      console.error('Error loading data:', error);
      setDefaultAssociates([]);
      setDefaultPaymentModes([]);
      setDefaultFromBanks([]);
    }
  }, []);

  const handleChildValues = useCallback(async () => {
    setValue('to_bank_account_id', '');
  }, [setValue]);

  // Used only when user CHANGES associate (intentional reset)
  const handleAssociateChange = useCallback(
    async (associateId: string) => {
      setValue('to_bank_account_id', ''); // only clear on user-triggered change
      await loadAssociateBanks(associateId);
    },
    [setValue, loadAssociateBanks],
  );

  // Change the function signature to accept optional deduction override
  const handleTotalAmountOnChange = (
    amount: number | string,
    deductionOverride?: number | string, // ← add this
  ) => {
    const total = parseFloat(String(amount)) || 0;
    setTotalAmount(total);

    const taxes = getValues('items') as Array<Record<string, any>>;
    let totalTax = 0;
    taxes?.forEach((tax, index) => {
      const taxAmount = calculateAmount(tax.tax_per, total);
      totalTax += taxAmount;
      setValue(`items.${index}.tax_amount`, taxAmount as any);
    });

    const afterTax = parseFloat((total - totalTax).toFixed(2));
    setAmountAfterTax(afterTax);

    // ← Use override if provided, otherwise fall back to state
    const deduction =
      parseFloat(String(deductionOverride ?? otherDeduction)) || 0;
    const net = parseFloat((afterTax - deduction).toFixed(2));

    setNetAmount(net);
    setValue('net_amount_inr', net.toString());
  };

  const handleOtherDeductionOnChange = async (deduction: number | string) => {
    const deductionValue = parseFloat(String(deduction)) || 0;
    const afterTax = parseFloat(String(amountAfterTax)) || 0;

    if (deductionValue > afterTax) {
      setError('other_deductions', {
        type: 'manual',
        message: 'Other deductions cannot exceed the amount after tax',
      });
    } else {
      clearErrors('other_deductions');
    }

    const finalAmount = parseFloat((afterTax - deductionValue).toFixed(2));
    setOtherDeduction(deductionValue);
    setNetAmount(finalAmount);
    setValue('net_amount_inr', finalAmount.toString());
  };

  const onSubmit = useCallback(
    async (data: z.infer<typeof EditSubAgentBonusSchema>) => {
      try {
        const items = getValues(`items`) ?? [];
        let netAmount = 0;
        let totalTaxAmount = 0;

        items.forEach((item: Record<string, any>) => {
          totalTaxAmount += parseFloat(item.tax_amount) || 0;
        });
        totalTaxAmount = parseFloat(totalTaxAmount.toFixed(2));

        items.forEach((item: Record<string, any>) => {
          netAmount += parseFloat(item.commission_amount) || 0;
        });
        netAmount = parseFloat(netAmount.toFixed(2));
        data.id = String(record?.id ?? '');
        data.currency = items[0]?.tuition_fees_currency;
        data.associate_id = String(data.associate_id);
        data.from_bank_account_id = data.from_bank_account_id
          ? String(data.from_bank_account_id)
          : null;
        data.to_bank_account_id = data.to_bank_account_id
          ? String(data.to_bank_account_id)
          : null;
        data.payment_mode_id = String(data.payment_mode_id);
        if (data.payment_mode_id === '1') {
          data.from_bank_account_id = '';
          data.to_bank_account_id = '';
          data.transaction_id = '';
        }
        data.other_deductions =
          data.other_deductions !== '' ? data.other_deductions : '0';

        data.total_tax_amount = String(totalTaxAmount);
        const post = { ...data, items };

        delete post.items;

        post.tax_details =
          items && items.length > 0 ? JSON.stringify(items) : null;

        const response = (await globalApiPost(
          API_ENDPOINTS.SUB_AGENT_BONUS.EDIT,
          post,
          false,
        )) as UnknownRecord;

        if (!response?.success) {
          showError((response as any).errors, C_M.UPDATE_FAILED);
        } else {
          showSuccess(C_M.CREATE_SUCCESS);
          onSuccess?.();
          setIsOpen(false);
          handlePaginatedRecords(1, {});
          form.reset();
        }
      } catch (error) {
        console.error('Submission error:', error);
        showError(error, C_M.SUBMIT_ERROR);
      }
    },
    [handlePaginatedRecords, getValues, record?.id],
  );

  return (
    <Dialog key={record.id} open={isOpen} onOpenChange={handleOpenChange}>
      <DialogTrigger asChild>
        {triggerIcon || (
          <Button className="button-action">
            <CommonImage
              src="/main/edit-icon.png"
              width={15}
              height={15}
              alt={'Edit Record'}
              classname="info-icon"
            />
          </Button>
        )}
      </DialogTrigger>

      <DialogContent
        aria-describedby={undefined}
        className="modal-common-widget w-full max-w-7xl p-0 m-0 table-modal-settings state-widget"
        onInteractOutside={(e) => e.preventDefault()}
        onEscapeKeyDown={(e) => e.preventDefault()}
        onClick={(e) => e.stopPropagation()}
        data-dialog-id="edit-dialog"
      >
        <DialogTitle className="p-5 modal-header">
          Edit Sub Agent Bonus
        </DialogTitle>
        <DialogDescription>{''}</DialogDescription>
        <DialogClose asChild>
          <button
            onClick={() => setIsOpen(false)}
            className="dialog-close absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none z-[9]"
            aria-label="Close"
          >
            <CommonImage
              src="/main/cross-arrow.webp"
              width={15}
              height={15}
              alt="Close"
              classname="dialog-close-img"
            />
          </button>
        </DialogClose>
        <VisuallyHidden>
          <DialogTitle>Hidden Title</DialogTitle>
        </VisuallyHidden>

        <Form {...form}>
          <form
            onSubmit={form.handleSubmit(onSubmit, (errors) => {
              console.log('Validation failed:', errors);
            })}
            encType="multipart/form-data"
          >
            <Text className="main-scroll-widget">
              <Text className="flex flex-wrap p-2 form-mid mt-0">
                <>
                  <FormField
                    control={control}
                    name="associate_id"
                    render={({ field }) => (
                      <SearchableSelect
                        field={field}
                        label="Associate"
                        placeholder="Choose Associate"
                        defaultValue={String(
                          record.associate_id || field.value,
                        )}
                        options={defaultAssociates.map((item: any) => ({
                          id: String(item.id),
                          name: item.name,
                        }))}
                        isOpen={dropdownStates.associate_id}
                        onOpenChange={() => toggleDropdown('associate_id')}
                        onSelect={(value) => {
                          field.onChange(String(value));
                          handleChildValues();
                          clearErrors('associate_id');
                          setDropdownStates((prev) => ({
                            ...prev,
                            associate_id: false,
                          }));
                          handleAssociateChange(String(value));
                        }}
                        required
                      />
                    )}
                  />

                  <div className="space-y-2 w-full md:w-1/2 lg:w-1/4 p-2 relative">
                    <label className="text-sm font-bold">
                      <span className="text-red-600 pl-1">*</span>
                      Total Amount
                    </label>
                    <FormField
                      control={control}
                      name="total_amount"
                      render={({ field }) => (
                        <FormItem className="space-y-2 w-full rounded-full">
                          <FormControl>
                            <Input
                              {...field}
                              minLength={1}
                              maxLength={13}
                              type="text"
                              className="rounded-full border-gray-600 shadow-none focus-within:shadow-none hover:shadow-none focus:shadow-none"
                              placeholder="Enter Total Amount"
                              value={field.value}
                              onChange={(e) => {
                                if (/^\d*\.?\d*$/.test(e.target.value)) {
                                  field.onChange(e.target.value);
                                  handleTotalAmountOnChange(e.target.value);
                                }
                              }}
                              onBlur={field.onBlur}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </div>

                  <TaxSection
                    control={
                      form.control as unknown as Control<FormDataWithTaxDetails>
                    }
                    name="items"
                    record={record}
                    totalAmount={totalAmount}
                    amountAfterTax={amountAfterTax}
                    setAmountAfterTax={setAmountAfterTax}
                    otherDeduction={otherDeduction}
                    setNetAmount={setNetAmount}
                  />

                  <div className="space-y-2 w-full md:w-1/2 lg:w-1/4 p-2 relative">
                    <label className="text-sm font-bold">
                      Other Deductions
                    </label>
                    <FormField
                      control={control}
                      name="other_deductions"
                      render={({ field }) => (
                        <FormItem className="space-y-2 w-full rounded-full">
                          <FormControl>
                            <Input
                              {...field}
                              minLength={1}
                              maxLength={13}
                              type="text"
                              className="rounded-full border-gray-600 shadow-none focus-within:shadow-none hover:shadow-none focus:shadow-none"
                              placeholder="Enter Other Deductions"
                              value={
                                Number(field.value) > 0
                                  ? String(field.value)
                                  : ''
                              }
                              onChange={(e) => {
                                const value = e.target.value;

                                if (value === '') {
                                  field.onChange('');
                                  handleOtherDeductionOnChange(0);
                                  setError('other_deductions', {
                                    type: 'manual',
                                    message: '',
                                  });
                                  return;
                                }

                                if (/^\d*\.?\d*$/.test(value)) {
                                  field.onChange(value);
                                  handleOtherDeductionOnChange(value);
                                }
                              }}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </div>

                  <div className="space-y-2 w-full md:w-1/2 lg:w-3/4 p-2 relative">
                    <label className="text-sm font-bold">
                      Deduction Reason
                    </label>
                    <FormField
                      control={control}
                      name="deduction_reason"
                      render={({ field }) => (
                        <FormItem className="space-y-2 w-full rounded-full">
                          <FormControl>
                            <Input
                              {...field}
                              minLength={1}
                              maxLength={500}
                              type="text"
                              className="rounded-full border-gray-600 shadow-none focus-within:shadow-none hover:shadow-none focus:shadow-none"
                              placeholder="Enter Deduction Reason"
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </div>

                  <div className="space-y-2 w-full md:w-1/2 lg:w-1/4 p-2 relative">
                    <label className="text-sm font-bold">
                      <span className="text-red-600 pl-1">*</span>
                      Net Amount in INR
                    </label>
                    <FormField
                      control={control}
                      name="net_amount_inr"
                      render={({ field }) => (
                        <FormItem className="space-y-2 w-full rounded-full">
                          <FormControl>
                            <Input
                              {...field}
                              minLength={1}
                              maxLength={13}
                              readOnly={true}
                              type="text"
                              value={netAmount}
                              className="rounded-full border-gray-600 shadow-none focus-within:shadow-none hover:shadow-none focus:shadow-none"
                              placeholder="Enter Net Amount in INR"
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </div>

                  <div className="space-y-2 w-full md:w-1/2 lg:w-1/4 p-2 relative">
                    <label className="text-sm font-bold">
                      <span className="text-red-600 pl-1">*</span>
                      Payment Date
                    </label>
                    <FormField
                      control={control}
                      name="payment_date"
                      rules={{ required: 'Payment date is required' }}
                      render={({ field }) => (
                        <FormItem className="space-y-2 w-full rounded-full">
                          <FormControl>
                            <Input
                              {...field}
                              type="text"
                              inputMode="numeric"
                              maxLength={10}
                              placeholder="DD/MM/YYYY"
                              className="rounded-full border-gray-600 shadow-none focus-within:shadow-none hover:shadow-none focus:shadow-none"
                              onChange={(e) => {
                                const maskedValue = maskDate(e.target.value);
                                field.onChange(maskedValue);
                                const error = validateInputDate(
                                  maskedValue,
                                  DateMode.PAST_CURRENT,
                                );
                                if (error) {
                                  setError('payment_date', { message: error });
                                } else {
                                  clearErrors('payment_date');
                                }
                              }}
                              onBlur={(e) => {
                                const value = e.target.value;
                                const error = validateInputDate(
                                  value,
                                  DateMode.PAST_CURRENT,
                                );
                                if (error) {
                                  setError('payment_date', { message: error });
                                } else {
                                  clearErrors('payment_date');
                                }
                              }}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </div>

                  <FormField
                    control={control}
                    name="payment_mode_id"
                    render={({ field }) => (
                      <SearchableSelect
                        field={field}
                        label="Payment Mode"
                        placeholder="Choose Payment Mode"
                        defaultValue={String(
                          record.payment_mode_id || field.value,
                        )}
                        options={defaultPaymentModes.map((item: any) => ({
                          id: item.id,
                          name: item.name,
                        }))}
                        isOpen={dropdownStates.payment_mode_id}
                        onOpenChange={() => toggleDropdown('payment_mode_id')}
                        onSelect={(value) => {
                          field.onChange(value);
                          clearErrors('payment_mode_id');
                          setPaymentMode(Number(value));
                          setDropdownStates((prev) => ({
                            ...prev,
                            payment_mode_id: false,
                          }));
                        }}
                        required
                      />
                    )}
                  />
                  {!bankAccountDependentPaymentMode.includes(paymentMode) && (
                    <>
                      <FormField
                        control={control}
                        name="from_bank_account_id"
                        render={({ field }) => (
                          <SearchableSelect
                            field={field}
                            label="Company Bank Account"
                            placeholder="Choose Company Bank Account"
                            defaultValue={String(
                              record.from_bank_account_id || field.value,
                            )}
                            options={defaultFromBanks.map((item: any) => ({
                              id: String(item.id),
                              name: item.name,
                            }))}
                            isOpen={dropdownStates.from_bank_account_id}
                            onOpenChange={() =>
                              toggleDropdown('from_bank_account_id')
                            }
                            onSelect={(value) => {
                              field.onChange(value);
                              clearErrors('from_bank_account_id');
                              setDropdownStates((prev) => ({
                                ...prev,
                                from_bank_account_id: false,
                              }));
                            }}
                            required={true}
                          />
                        )}
                      />

                      <FormField
                        control={control}
                        name="to_bank_account_id"
                        render={({ field }) => (
                          <SearchableSelect
                            field={field}
                            label="Associate Bank Account"
                            placeholder="Choose Associate Bank Account"
                            defaultValue={String(
                              record.to_bank_account_id || field.value,
                            )}
                            options={defaultToBanks.map((item: any) => ({
                              id: String(item.id),
                              name: item.name,
                            }))}
                            isOpen={dropdownStates.to_bank_account_id}
                            onOpenChange={() =>
                              toggleDropdown('to_bank_account_id')
                            }
                            onSelect={(value) => {
                              field.onChange(value);
                              clearErrors('to_bank_account_id');
                              setDropdownStates((prev) => ({
                                ...prev,
                                to_bank_account_id: false,
                              }));
                            }}
                            required={true}
                          />
                        )}
                      />

                      <div className="space-y-2 w-full md:w-1/2 lg:w-1/4 p-2 relative">
                        <label className="text-sm font-bold">
                          <span className="text-red-600 pl-1">*</span>
                          Transaction ID
                        </label>
                        <FormField
                          control={control}
                          name="transaction_id"
                          render={({ field }) => (
                            <FormItem className="space-y-2 w-full rounded-full">
                              <FormControl>
                                <Input
                                  {...field}
                                  minLength={1}
                                  maxLength={500}
                                  type="text"
                                  className="rounded-full border-gray-600 shadow-none focus-within:shadow-none hover:shadow-none focus:shadow-none"
                                  placeholder="Enter Transaction ID"
                                />
                              </FormControl>
                              <FormMessage />
                            </FormItem>
                          )}
                        />
                      </div>
                    </>
                  )}
                  <div className="flex flex-row items-end gap-4 w-full">
                    <FormField
                      control={control}
                      name="remarks"
                      render={({ field }) => (
                        <FormItem className="w-full rounded-full">
                          <FormLabel className="no-error-styles font-bold">
                            Remarks
                          </FormLabel>

                          <FormControl className="input-pl-50">
                            <Textarea
                              {...field}
                              rows={4}
                              placeholder="Enter remarks here..."
                              value={field.value || ''}
                              onChange={field.onChange}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </div>
                </>
              </Text>
            </Text>
            <Text className="modal-footer flex justify-end items-end footer-modal text-right gap-2 m-0 pr-4 p-2">
              <DialogClose asChild>
                <Button
                  type="button"
                  className="m-0 filter-search-btn tracking-wider w-40 primary-button"
                >
                  Cancel
                </Button>
              </DialogClose>
              <Button
                type="submit"
                disabled={isSubmitting}
                className="m-0 filter-search-btn tracking-wider w-40 primary-button"
              >
                {isSubmitting && (
                  <span className="h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" />
                )}
                {isSubmitting ? 'Updating...' : 'Edit'}
              </Button>
            </Text>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  );
};

export default EditSubAgentBonus;
