'use client';

import { useState } from 'react';
import { Form, Formik } from 'formik';
import * as Yup from 'yup';
import { useRouter } from 'next/navigation';
import FormikInput from '@/Component/Common/Forms/FormikInput';
import FormLabel from '@/Component/Common/Forms/FormLabel';
import ErrorMessages from '@/Utils/ErrorMessages';
import GradientButton from '@/Component/Common/Forms/GradientButton';
import BorderButton from '@/Component/Common/Forms/BorderButton';
import { LoaderSVG } from '@/Component/Common/SVGs/CommonSVG';
import { CustomToast } from '@/Utils/CustomToast';
import usePost from '@/Utils/Hooks/usePost';
import CustomFetch from '@/Utils/APIRequest/AxiosInstance';
import { useQuery } from '@tanstack/react-query';
import { AdminPaymentMethodListAPI } from '@/Utils/APIRequest/Endpoints';
import { PaymentMethodField, PaymentMethodFormPayload } from './types';
import DynamicFieldEditor from './DynamicFieldEditor';
import PrimaryButton from '@/Component/Common/Forms/PrimaryButton';
import ConfirmationModal from '@/Component/Common/Modal/ConfirmationModal';

const nameSchema = Yup.object().shape({
  name: Yup.string().trim().required('Payment method name is required'),
  json_text: Yup.array()
    .of(
      Yup.object().shape({
        key: Yup.string().required(),
        label: Yup.string().required(),
        type: Yup.string().required(),
        required: Yup.boolean(),
        options: Yup.array().optional(),
      })
    )
    .min(1, 'At least one field is required')
    .required('At least one field is required'),
});

interface PaymentMethodFormProps {
  id?: number | string | null;
  onSuccess?: () => void;
}

export default function PaymentMethodForm({ id, onSuccess }: PaymentMethodFormProps) {
  const router = useRouter();
  const isEdit = !!id;
  const [confirmEditOpen, setConfirmEditOpen] = useState(false);
  const [pendingPayload, setPendingPayload] = useState<PaymentMethodFormPayload | null>(null);

  const { data: detailData, isPending: detailLoading } = useQuery({
    queryKey: [AdminPaymentMethodListAPI, id],
    queryFn: () => CustomFetch({ url: `${AdminPaymentMethodListAPI}/${id}` }, null, false),
    enabled: !!id,
    refetchOnWindowFocus: false,
    select: (data: any) => data?.data?.data ?? data?.data,
  });

  const { isPending: submitLoading, mutate } = usePost(
    id ? `${AdminPaymentMethodListAPI}/${id}` : AdminPaymentMethodListAPI,
    null,
    (response) => {
      if (response?.status === 200 || response?.status === 201) {
        CustomToast(
          'success',
          isEdit ? 'Payment method updated successfully' : 'Payment method created successfully'
        );
        if (onSuccess) onSuccess();
        else router.back();
      }
    },
    isEdit ? 'put' : ''
  );

  const initialValues: PaymentMethodFormPayload = {
    name: (isEdit && detailData?.name) || '',
    json_text: (isEdit && detailData?.json_text) || [],
  };

  const normalizeField = (field: PaymentMethodField): PaymentMethodField => ({
    key: field.key.trim() || field.label.toLowerCase().replace(/\s+/g, '_'),
    label: field.label.trim(),
    type: field.type,
    required: !!field.required,
    ...(field.type === 'select' && {
      options: (field.options || []).map((opt) => String(opt).trim()).filter(Boolean),
    }),
  });

  const buildPayload = (values: PaymentMethodFormPayload): PaymentMethodFormPayload => ({
    name: values.name.trim(),
    json_text: (values.json_text || [])
      .filter((f) => f.label && f.label.trim())
      .map(normalizeField),
  });

  const hasJsonTextChanged = (payload: PaymentMethodFormPayload) => {
    const originalFields = ((detailData?.json_text as PaymentMethodField[]) || [])
      .filter((f) => f.label && f.label.trim())
      .map(normalizeField);
    return JSON.stringify(payload.json_text) !== JSON.stringify(originalFields);
  };

  if (isEdit && detailLoading) {
    return (
      <div className="py-12 flex justify-center">
        <LoaderSVG />
      </div>
    );
  }

  return (
    <Formik
      enableReinitialize
      initialValues={initialValues}
      validationSchema={nameSchema}
      onSubmit={(values) => {
        // Validate that at least one field exists
        if (!values.json_text || values.json_text.length === 0) {
          CustomToast('error', 'At least one field is required');
          return;
        }

        const payload = buildPayload(values);

        // Double check after filtering
        if (payload.json_text.length === 0) {
          CustomToast('error', 'At least one valid field is required');
          return;
        }

        const linkedInfluencerCount = Number(detailData?.influencerPaymentMethodsCount ?? 0);
        if (isEdit && linkedInfluencerCount > 0 && hasJsonTextChanged(payload)) {
          setPendingPayload(payload);
          setConfirmEditOpen(true);
          return;
        }

        (mutate as any)(payload);
      }}
    >
      {({ errors, touched, values, setFieldValue, setFieldTouched }) => (
        <Form >
          <div className='flex items-center justify-between pb-4 border-b border-lightGray mb-8'>
            <h1 className='lg:text-2xl md:text-xl text-lg font-bold'>{isEdit ? 'Edit' : 'Add'} Payment Method</h1>
            <div className="flex items-center gap-2">
              <PrimaryButton
                buttonType="submit"
                customClass="flex justify-center items-center max-w-40"
                disabled={submitLoading}
              >
                Submit
                {submitLoading && <LoaderSVG customClass="ml-2.5" />}
              </PrimaryButton>
              <BorderButton buttonType="button" onClick={() => router.back()}>
                Cancel
              </BorderButton>
            </div>
          </div>
          <div className="mb-4">
            <FormLabel title="Payment method name" isRequired />
            <FormikInput
              skeletonLoading={isEdit && detailLoading}
              inputProps={{
                type: 'text',
                name: 'name',
                placeholder: 'e.g. FPS, Bank Account',
              }}
            />
            <ErrorMessages fieldName="name" errors={errors} touched={touched} />
          </div>

          <div className="mb-5">
            <DynamicFieldEditor
              json_text={values.json_text}
              onChange={(json_text: PaymentMethodField[]) => {
                setFieldValue('json_text', json_text);
                setFieldValue('json_text_touched', true);
              }}
              errors={errors as Record<string, string>}
              touched={touched as Record<string, boolean>}
              getFieldProps={(name) => ({
                name,
                value: (values as any)[name],
                onChange: (e: any) => setFieldValue(name, e.target.value),
                onBlur: () => { },
              })}
            />
            <ErrorMessages fieldName="json_text" errors={errors} touched={touched} />
          </div>
          {confirmEditOpen && (
            <ConfirmationModal
              modal={confirmEditOpen}
              setModal={() => {
                setConfirmEditOpen(false);
                setPendingPayload(null);
              }}
              args={{
                message:
                  'This payment method is already used by influencers. Are you sure you want to update its fields?',
                buttonText: 'Update',
              }}
              loader={submitLoading}
              callbackFunction={() => {
                if (!pendingPayload) {
                  setConfirmEditOpen(false);
                  return;
                }
                (mutate as any)(pendingPayload);
                setPendingPayload(null);
                setConfirmEditOpen(false);
              }}
            />
          )}

        </Form>
      )}
    </Formik>
  );
}
