'use client';

import { useState } from 'react';
import { Form, Formik } from 'formik';
import * as Yup from 'yup';
import Select from 'react-select';
import { useQuery } from '@tanstack/react-query';
import CustomFetch from '@/Utils/APIRequest/AxiosInstance';
import {
  CountriesAPI,
  AdminPaymentMethodListAPI,
  AdminCountryPaymentMethodsAPI,
} from '@/Utils/APIRequest/Endpoints';
import { useTranslation } from '@/Utils/Hooks/useTranslate';
import GradientButton from '@/Component/Common/Forms/GradientButton';
import BorderButton from '@/Component/Common/Forms/BorderButton';
import { LoaderSVG } from '@/Component/Common/SVGs/CommonSVG';
import FormLabel from '@/Component/Common/Forms/FormLabel';
import ErrorMessages from '@/Utils/ErrorMessages';
import Modal from '@/Component/Common/Modal';
import usePost from '@/Utils/Hooks/usePost';
import { CustomToast } from '@/Utils/CustomToast';
import CountryPaymentTable from './CountryPaymentTable';
import type { CountryWithPaymentMethods, PaymentMethodRecord } from './types';
import ConfirmationModal from '@/Component/Common/Modal/ConfirmationModal';

type CountryOption = { value: number | string; label: string };
type PaymentMethodOption = {
  value: number | string;
  label: string;
  influencerPaymentMethodsCount: number;
};

const assignSchema = Yup.object().shape({
  country_id: Yup.string().required('Please select a country'),
  payment_method_ids: Yup.array().min(1, 'Select at least one payment method').required('Select at least one payment method'),
});

export default function CountryPaymentSection() {
  const { translations } = useTranslation();
  const [assignModalOpen, setAssignModalOpen] = useState(false);
  const [preselectedCountry, setPreselectedCountry] = useState<CountryWithPaymentMethods | null>(null);
  const [removeConfirmOpen, setRemoveConfirmOpen] = useState(false);
  const [pendingRemoval, setPendingRemoval] = useState<{
    removedOption: PaymentMethodOption;
    nextSelected: PaymentMethodOption[];
  } | null>(null);
  const [search, setSearch] = useState('');
  const [params, setParams] = useState({
    page: 1,
    per_page: 50,
    sort_by: 'country_name',
    sort: 'ASC'
  });

  // Table API: country–payment assignments list
  const { data, isPending, refetch, fetchStatus } = useQuery({
    queryKey: [AdminCountryPaymentMethodsAPI, search, params],
    queryFn: () =>
      CustomFetch({ url: AdminCountryPaymentMethodsAPI, params: { search, ...params } }, null, false),
    refetchOnWindowFocus: false,
    select: (res: any) => res?.data,
  });

  // Countries listing API: for dropdown only
  const { data: countriesListData } = useQuery({
    queryKey: [CountriesAPI],
    queryFn: () => CustomFetch({ url: CountriesAPI }, null, false),
    refetchOnWindowFocus: false,
    enabled: assignModalOpen,
    select: (data: any) => data?.data?.data ?? data?.data ?? [],
  });

  // Payment method list API: for payment methods dropdown
  const { data: paymentMethodsListData } = useQuery({
    queryKey: [AdminPaymentMethodListAPI],
    queryFn: () => CustomFetch({ url: AdminPaymentMethodListAPI, params: { per_page: 500, is_active: true } }, null, false),
    refetchOnWindowFocus: false,
    enabled: assignModalOpen,
    select: (data: any) => data?.data?.data ?? data?.data ?? [],
  });

  // Detail API: fetch country's payment method assignments when editing
  const { data: detailData, isPending: detailLoading } = useQuery({
    queryKey: [AdminCountryPaymentMethodsAPI, preselectedCountry?.id],
    queryFn: () => CustomFetch({ url: `${AdminCountryPaymentMethodsAPI}/${preselectedCountry?.id}` }, null, false),
    refetchOnWindowFocus: false,
    enabled: !!preselectedCountry?.id && assignModalOpen,
    select: (data: any) => data?.data?.data ?? data?.data,
  });

  const countriesRaw = Array.isArray(countriesListData) ? countriesListData : [];
  const paymentMethodsRaw: PaymentMethodRecord[] = Array.isArray(paymentMethodsListData) ? paymentMethodsListData : [];

  const countryOptions: CountryOption[] = countriesRaw.map((c: any) => ({
    value: c.id,
    label: c.country_name ?? c.name ?? String(c.id),
  }));

  const paymentMethodOptions: PaymentMethodOption[] = paymentMethodsRaw.map((pm: PaymentMethodRecord) => ({
    value: pm.id,
    label: pm.name,
    influencerPaymentMethodsCount: Number(pm.influencerPaymentMethodsCount ?? 0),
  }));

  const openAssignModal = (country?: CountryWithPaymentMethods | null) => {
    setAssignModalOpen(true);
    setPreselectedCountry(country ?? null);
  };

  const getInitialValues = () => {
    // Use detail API data if available (when editing), otherwise fallback to preselectedCountry from table
    const country = detailData ?? preselectedCountry;
    const countryId = country?.id ?? '';

    // Get payment method IDs from detail API or table row
    const existingIds = (country?.countryPaymentMethods ?? country?.payment_methods ?? [])
      .filter((pm: any) => pm.is_active !== false)
      .map((pm: any) => pm.payment_method_id ?? pm.payment_method?.id ?? pm.id ?? pm);
    const existingIdsStr = existingIds.map(String);

    const selectedOptions = existingIdsStr.map((id) => {
      const existingAssignment = (country?.countryPaymentMethods ?? country?.payment_methods ?? []).find(
        (p: any) => String(p.payment_method_id ?? p.payment_method?.id ?? p.id ?? p) === id
      );
      const listOption = paymentMethodOptions.find((opt) => String(opt.value) === id);

      return {
        value: id,
        label: existingAssignment?.payment_method?.name ?? listOption?.label ?? id,
        influencerPaymentMethodsCount: Number(
          existingAssignment?.influencerPaymentMethodsCount ??
            listOption?.influencerPaymentMethodsCount ??
            0
        ),
      };
    });

    const countryOption = countryId
      ? (countryOptions.find((o) => String(o.value) === String(countryId)) ?? {
        value: countryId,
        label: (country as any)?.country_name ?? country?.name ?? String(countryId),
      })
      : null;

    return {
      country_id: countryId ? String(countryId) : '',
      country: countryOption,
      payment_method_ids: existingIdsStr,
      payment_methods: selectedOptions,
    };
  };

  const { isPending: saveLoading, mutate: saveMutate } = usePost(
    AdminCountryPaymentMethodsAPI,
    null,
    (response) => {
      if (response?.status === 200 || response?.status === 201) {
        CustomToast('success', 'Country payment methods updated successfully');
        refetch();
        setAssignModalOpen(false);
        setPreselectedCountry(null);
      }
    },
    ''
  );

  return (
    <>
      <CountryPaymentTable
        searchBtnProps={{
          setSearch,
          title: 'Assign Methods',
          callBack: () => openAssignModal(null),
          buttonRequired: true,
        }}
        apiData={{
          data,
          params,
          setParams,
          isPending,
          refetch,
          fetchStatus,
        }}
        search={search}
        onEdit={(row) => openAssignModal(row)}
        translations={translations}
      />

      {assignModalOpen && (
        <Modal
          modalSize="md:w-full max-w-lg"
          childMainClass="max-h-[90vh] overflow-y-auto"
          modal={assignModalOpen}
          setModal={() => {
            setAssignModalOpen(false);
            setPreselectedCountry(null);
            setRemoveConfirmOpen(false);
            setPendingRemoval(null);
          }}
          headerTitle={preselectedCountry ? `Edit Assigned Payment Methods` : 'Assign Payment Methods'}
        >
          {detailLoading && preselectedCountry ? (
            <div className="py-8 flex justify-center">
              <LoaderSVG />
            </div>
          ) : (
            <Formik
              enableReinitialize
              initialValues={getInitialValues()}
              validationSchema={assignSchema}
              onSubmit={(values) => {
                const countryId = values.country_id;
                const payload:any = {
                  country_id: countryId,
                  payment_method_ids: values.payment_method_ids ?? [],
                };
                saveMutate(payload);
              }}
            >
              {({ errors, touched, setFieldValue, setFieldTouched, values }) => {
                const applySelection = (selected: PaymentMethodOption[]) => {
                  setFieldValue('payment_methods', selected);
                  setFieldValue(
                    'payment_method_ids',
                    selected.map((o) => o.value)
                  );
                  setFieldTouched('payment_method_ids', true);
                };

                const handlePaymentMethodChange = (selected: readonly PaymentMethodOption[], actionMeta: any) => {
                  const nextSelected = (selected ?? []) as PaymentMethodOption[];
                  const removedOptionFromAction =
                    (actionMeta?.removedValue as PaymentMethodOption | undefined) ||
                    (actionMeta?.option as PaymentMethodOption | undefined);
                  const removedOptionFromSelected = (values.payment_methods as PaymentMethodOption[] | undefined)?.find(
                    (option) => String(option.value) === String(removedOptionFromAction?.value)
                  );
                  const removedOption = removedOptionFromSelected ?? removedOptionFromAction;
                  const removedValues = (actionMeta?.removedValues as PaymentMethodOption[] | undefined) ?? [];

                  const removeAction = ['remove-value', 'pop-value', 'deselect-option'].includes(
                    actionMeta?.action
                  );
                  const clearAction = actionMeta?.action === 'clear';
                  const clearBlockedOption = removedValues.find(
                    (option) => Number(option.influencerPaymentMethodsCount ?? 0) > 0
                  );

                  const shouldConfirmRemove =
                    (removeAction &&
                      removedOption &&
                      Number(removedOption.influencerPaymentMethodsCount ?? 0) > 0) ||
                    (clearAction && clearBlockedOption);

                  const selectedRemovedOption = removedOption ?? clearBlockedOption;
                  if (shouldConfirmRemove && selectedRemovedOption) {
                    setPendingRemoval({ removedOption: selectedRemovedOption, nextSelected });
                    setRemoveConfirmOpen(true);
                    return;
                  }

                  applySelection(nextSelected);
                };

                return (
                  <>
                    <Form>
                      <div className="space-y-4 mb-5">
                    <div>
                      <FormLabel title="Select country" isRequired />
                      <Select<CountryOption>
                        isClearable
                        isSearchable
                        placeholder="Search and select country..."
                        options={countryOptions}
                        value={values.country}
                        maxMenuHeight={150}
                        onChange={(option) => {
                          setFieldValue('country', option);
                          setFieldValue('country_id', option?.value ?? '');
                          setFieldTouched('country_id', true);
                        }}
                        onBlur={() => setFieldTouched('country_id', true)}
                        classNamePrefix="assign-select"
                        className="assign-select-container text-base font-medium text-black"
                        styles={{
                          control: (base) => ({ ...base, minHeight: 48, borderColor: 'var(--gray)', borderRadius: 12 }),
                          menu: (base) => ({ ...base, zIndex: 60 }),
                        }}
                      />
                      <ErrorMessages fieldName="country_id" errors={errors} touched={touched} />
                    </div>
                    <div>
                      <FormLabel title="Select payment methods" isRequired />
                      <Select<PaymentMethodOption, true>
                        isMulti
                        isSearchable
                        placeholder="Search and select payment methods..."
                        options={paymentMethodOptions}
                        value={values.payment_methods}
                        maxMenuHeight={150}
                        onChange={handlePaymentMethodChange}
                        onBlur={() => setFieldTouched('payment_method_ids', true)}
                        classNamePrefix="assign-select"
                        className="assign-select-container text-base font-medium text-black"
                        styles={{
                          control: (base) => ({ ...base, minHeight: 48, borderColor: 'var(--gray)', borderRadius: 12 }),
                          menu: (base) => ({ ...base, zIndex: 60, maxHeight: 150 }),
                        }}
                      />
                      <ErrorMessages fieldName="payment_method_ids" errors={errors} touched={touched} />
                    </div>
                    {paymentMethodOptions.length === 0 && (
                      <p className="text-gray text-sm">No payment methods yet. Add them in the Payment Methods tab.</p>
                    )}
                      </div>
                      <div className="flex justify-center gap-2">
                        <GradientButton
                          buttonType="submit"
                          customClass="flex items-center justify-center max-w-40"
                          disabled={saveLoading}
                        >
                          Save
                          {saveLoading && <LoaderSVG customClass="ml-2.5" />}
                        </GradientButton>
                        <BorderButton
                          buttonType="button"
                          onClick={() => {
                            setAssignModalOpen(false);
                            setPreselectedCountry(null);
                          }}
                        >
                          Cancel
                        </BorderButton>
                      </div>
                    </Form>
                    {removeConfirmOpen && (
                      <ConfirmationModal
                        modal={removeConfirmOpen}
                        setModal={() => {
                          setRemoveConfirmOpen(false);
                          setPendingRemoval(null);
                        }}
                        args={{
                          message: `This payment method already has influencer entries. Are you sure you want to remove "${pendingRemoval?.removedOption?.label}" from this country?`,
                          buttonText: 'Remove',
                        }}
                        callbackFunction={() => {
                          if (pendingRemoval) {
                            applySelection(pendingRemoval.nextSelected);
                          }
                          setPendingRemoval(null);
                          setRemoveConfirmOpen(false);
                        }}
                        translations={translations}
                      />
                    )}
                  </>
                );
              }}
            </Formik>
          )}
        </Modal>
      )}
    </>
  );
}
