/**
 * Store pour les formulaires Banking - COOP-CA AMIFOND
 *
 * Gestion de l'état des formulaires, validations et soumissions
 */

import { create } from "zustand";
import { devtools } from "zustand/middleware";
import {
  AccountCreateFormData,
  TransferCreateFormData,
  TransactionCreateFormData,
  accountCreateSchema,
  transferCreateSchema,
  transactionCreateSchema,
} from "@/types/banking";

// Types pour l'état des formulaires
interface FormState<T> {
  data: T;
  errors: Record<string, string>;
  touched: Record<string, boolean>;
  isValid: boolean;
  isSubmitting: boolean;
  isDirty: boolean;
}

interface BankingFormsState {
  // États des formulaires
  accountCreate: FormState<AccountCreateFormData>;
  transferCreate: FormState<TransferCreateFormData>;
  transactionCreate: FormState<TransactionCreateFormData>;

  // États des modales/dialogs
  isAccountCreateModalOpen: boolean;
  isTransferCreateModalOpen: boolean;
  isTransactionCreateModalOpen: boolean;
  isDepositModalOpen: boolean;
  isWithdrawalModalOpen: boolean;

  // État global des formulaires
  hasUnsavedChanges: boolean;
}

interface BankingFormsActions {
  // Actions formulaire compte
  updateAccountCreateForm: (data: Partial<AccountCreateFormData>) => void;
  validateAccountCreateForm: () => boolean;
  resetAccountCreateForm: () => void;
  setAccountCreateField: (field: keyof AccountCreateFormData, value: string | number) => void;
  touchAccountCreateField: (field: keyof AccountCreateFormData) => void;
  setAccountCreateSubmitting: (isSubmitting: boolean) => void;

  // Actions formulaire transfert
  updateTransferCreateForm: (data: Partial<TransferCreateFormData>) => void;
  validateTransferCreateForm: () => boolean;
  resetTransferCreateForm: () => void;
  setTransferCreateField: (field: keyof TransferCreateFormData, value: string | number) => void;
  touchTransferCreateField: (field: keyof TransferCreateFormData) => void;
  setTransferCreateSubmitting: (isSubmitting: boolean) => void;

  // Actions formulaire transaction
  updateTransactionCreateForm: (data: Partial<TransactionCreateFormData>) => void;
  validateTransactionCreateForm: () => boolean;
  resetTransactionCreateForm: () => void;
  setTransactionCreateField: (field: keyof TransactionCreateFormData, value: string | number) => void;
  touchTransactionCreateField: (field: keyof TransactionCreateFormData) => void;
  setTransactionCreateSubmitting: (isSubmitting: boolean) => void;

  // Actions modales
  openAccountCreateModal: () => void;
  closeAccountCreateModal: () => void;
  openTransferCreateModal: () => void;
  closeTransferCreateModal: () => void;
  openTransactionCreateModal: () => void;
  closeTransactionCreateModal: () => void;
  openDepositModal: () => void;
  closeDepositModal: () => void;
  openWithdrawalModal: () => void;
  closeWithdrawalModal: () => void;

  // Actions générales
  resetAllForms: () => void;
  closeAllModals: () => void;
}

// Store type complet
type BankingFormsStore = BankingFormsState & BankingFormsActions;

// États initiaux des formulaires
const initialAccountCreateForm: FormState<AccountCreateFormData> = {
  data: {
    client_id: 0,
    account_type: "",
    currency: "XAF",
    overdraft_limit: "",
    interest_rate: "",
    notes: "",
  },
  errors: {},
  touched: {},
  isValid: false,
  isSubmitting: false,
  isDirty: false,
};

const initialTransferCreateForm: FormState<TransferCreateFormData> = {
  data: {
    from_account_id: 0,
    to_account_id: 0,
    amount: "",
    description: "",
    reference: "",
    scheduled_date: "",
  },
  errors: {},
  touched: {},
  isValid: false,
  isSubmitting: false,
  isDirty: false,
};

const initialTransactionCreateForm: FormState<TransactionCreateFormData> = {
  data: {
    account_id: 0,
    type: "deposit",
    amount: "",
    description: "",
    reference: "",
    beneficiary_account_id: undefined,
  },
  errors: {},
  touched: {},
  isValid: false,
  isSubmitting: false,
  isDirty: false,
};

// État initial
const initialState: BankingFormsState = {
  // États des formulaires
  accountCreate: initialAccountCreateForm,
  transferCreate: initialTransferCreateForm,
  transactionCreate: initialTransactionCreateForm,

  // États des modales
  isAccountCreateModalOpen: false,
  isTransferCreateModalOpen: false,
  isTransactionCreateModalOpen: false,
  isDepositModalOpen: false,
  isWithdrawalModalOpen: false,

  // État global
  hasUnsavedChanges: false,
};

// Fonctions utilitaires de validation
const validateForm = <T>(data: T, schema: any): { isValid: boolean; errors: Record<string, string> } => {
  try {
    schema.parse(data);
    return { isValid: true, errors: {} };
  } catch (error: any) {
    const errors: Record<string, string> = {};

    if (error.errors) {
      error.errors.forEach((err: any) => {
        if (err.path && err.path.length > 0) {
          errors[err.path[0]] = err.message;
        }
      });
    }

    return { isValid: false, errors };
  }
};

const checkIfDirty = <T>(current: T, initial: T): boolean => {
  return JSON.stringify(current) !== JSON.stringify(initial);
};

// Création du store
export const useBankingFormsStore = create<BankingFormsStore>()(
  devtools(
    (set, get) => ({
      ...initialState,

      // Actions formulaire compte
      updateAccountCreateForm: (data) => {
        const currentForm = get().accountCreate;
        const newData = { ...currentForm.data, ...data };
        const { isValid, errors } = validateForm(newData, accountCreateSchema);
        const isDirty = checkIfDirty(newData, initialAccountCreateForm.data);

        set({
          accountCreate: {
            ...currentForm,
            data: newData,
            errors,
            isValid,
            isDirty,
          },
          hasUnsavedChanges: isDirty || get().transferCreate.isDirty || get().transactionCreate.isDirty,
        });
      },

      validateAccountCreateForm: () => {
        const form = get().accountCreate;
        const { isValid, errors } = validateForm(form.data, accountCreateSchema);

        set({
          accountCreate: {
            ...form,
            errors,
            isValid,
            touched: Object.keys(form.data).reduce((acc, key) => ({ ...acc, [key]: true }), {}),
          },
        });

        return isValid;
      },

      resetAccountCreateForm: () => {
        set({
          accountCreate: initialAccountCreateForm,
          hasUnsavedChanges: get().transferCreate.isDirty || get().transactionCreate.isDirty,
        });
      },

      setAccountCreateField: (field, value) => {
        const currentForm = get().accountCreate;
        const newData = { ...currentForm.data, [field]: value };
        const { isValid, errors } = validateForm(newData, accountCreateSchema);
        const isDirty = checkIfDirty(newData, initialAccountCreateForm.data);

        set({
          accountCreate: {
            ...currentForm,
            data: newData,
            errors,
            isValid,
            isDirty,
          },
          hasUnsavedChanges: isDirty || get().transferCreate.isDirty || get().transactionCreate.isDirty,
        });
      },

      touchAccountCreateField: (field) => {
        const currentForm = get().accountCreate;
        set({
          accountCreate: {
            ...currentForm,
            touched: { ...currentForm.touched, [field]: true },
          },
        });
      },

      setAccountCreateSubmitting: (isSubmitting) => {
        const currentForm = get().accountCreate;
        set({
          accountCreate: {
            ...currentForm,
            isSubmitting,
          },
        });
      },

      // Actions formulaire transfert
      updateTransferCreateForm: (data) => {
        const currentForm = get().transferCreate;
        const newData = { ...currentForm.data, ...data };
        const { isValid, errors } = validateForm(newData, transferCreateSchema);
        const isDirty = checkIfDirty(newData, initialTransferCreateForm.data);

        set({
          transferCreate: {
            ...currentForm,
            data: newData,
            errors,
            isValid,
            isDirty,
          },
          hasUnsavedChanges: get().accountCreate.isDirty || isDirty || get().transactionCreate.isDirty,
        });
      },

      validateTransferCreateForm: () => {
        const form = get().transferCreate;
        const { isValid, errors } = validateForm(form.data, transferCreateSchema);

        set({
          transferCreate: {
            ...form,
            errors,
            isValid,
            touched: Object.keys(form.data).reduce((acc, key) => ({ ...acc, [key]: true }), {}),
          },
        });

        return isValid;
      },

      resetTransferCreateForm: () => {
        set({
          transferCreate: initialTransferCreateForm,
          hasUnsavedChanges: get().accountCreate.isDirty || get().transactionCreate.isDirty,
        });
      },

      setTransferCreateField: (field, value) => {
        const currentForm = get().transferCreate;
        const newData = { ...currentForm.data, [field]: value };
        const { isValid, errors } = validateForm(newData, transferCreateSchema);
        const isDirty = checkIfDirty(newData, initialTransferCreateForm.data);

        set({
          transferCreate: {
            ...currentForm,
            data: newData,
            errors,
            isValid,
            isDirty,
          },
          hasUnsavedChanges: get().accountCreate.isDirty || isDirty || get().transactionCreate.isDirty,
        });
      },

      touchTransferCreateField: (field) => {
        const currentForm = get().transferCreate;
        set({
          transferCreate: {
            ...currentForm,
            touched: { ...currentForm.touched, [field]: true },
          },
        });
      },

      setTransferCreateSubmitting: (isSubmitting) => {
        const currentForm = get().transferCreate;
        set({
          transferCreate: {
            ...currentForm,
            isSubmitting,
          },
        });
      },

      // Actions formulaire transaction
      updateTransactionCreateForm: (data) => {
        const currentForm = get().transactionCreate;
        const newData = { ...currentForm.data, ...data };
        const { isValid, errors } = validateForm(newData, transactionCreateSchema);
        const isDirty = checkIfDirty(newData, initialTransactionCreateForm.data);

        set({
          transactionCreate: {
            ...currentForm,
            data: newData,
            errors,
            isValid,
            isDirty,
          },
          hasUnsavedChanges: get().accountCreate.isDirty || get().transferCreate.isDirty || isDirty,
        });
      },

      validateTransactionCreateForm: () => {
        const form = get().transactionCreate;
        const { isValid, errors } = validateForm(form.data, transactionCreateSchema);

        set({
          transactionCreate: {
            ...form,
            errors,
            isValid,
            touched: Object.keys(form.data).reduce((acc, key) => ({ ...acc, [key]: true }), {}),
          },
        });

        return isValid;
      },

      resetTransactionCreateForm: () => {
        set({
          transactionCreate: initialTransactionCreateForm,
          hasUnsavedChanges: get().accountCreate.isDirty || get().transferCreate.isDirty,
        });
      },

      setTransactionCreateField: (field, value) => {
        const currentForm = get().transactionCreate;
        const newData = { ...currentForm.data, [field]: value };
        const { isValid, errors } = validateForm(newData, transactionCreateSchema);
        const isDirty = checkIfDirty(newData, initialTransactionCreateForm.data);

        set({
          transactionCreate: {
            ...currentForm,
            data: newData,
            errors,
            isValid,
            isDirty,
          },
          hasUnsavedChanges: get().accountCreate.isDirty || get().transferCreate.isDirty || isDirty,
        });
      },

      touchTransactionCreateField: (field) => {
        const currentForm = get().transactionCreate;
        set({
          transactionCreate: {
            ...currentForm,
            touched: { ...currentForm.touched, [field]: true },
          },
        });
      },

      setTransactionCreateSubmitting: (isSubmitting) => {
        const currentForm = get().transactionCreate;
        set({
          transactionCreate: {
            ...currentForm,
            isSubmitting,
          },
        });
      },

      // Actions modales
      openAccountCreateModal: () => set({ isAccountCreateModalOpen: true }),
      closeAccountCreateModal: () => {
        get().resetAccountCreateForm();
        set({ isAccountCreateModalOpen: false });
      },

      openTransferCreateModal: () => set({ isTransferCreateModalOpen: true }),
      closeTransferCreateModal: () => {
        get().resetTransferCreateForm();
        set({ isTransferCreateModalOpen: false });
      },

      openTransactionCreateModal: () => set({ isTransactionCreateModalOpen: true }),
      closeTransactionCreateModal: () => {
        get().resetTransactionCreateForm();
        set({ isTransactionCreateModalOpen: false });
      },

      openDepositModal: () => set({ isDepositModalOpen: true }),
      closeDepositModal: () => set({ isDepositModalOpen: false }),

      openWithdrawalModal: () => set({ isWithdrawalModalOpen: true }),
      closeWithdrawalModal: () => set({ isWithdrawalModalOpen: false }),

      // Actions générales
      resetAllForms: () => {
        set({
          accountCreate: initialAccountCreateForm,
          transferCreate: initialTransferCreateForm,
          transactionCreate: initialTransactionCreateForm,
          hasUnsavedChanges: false,
        });
      },

      closeAllModals: () => {
        set({
          isAccountCreateModalOpen: false,
          isTransferCreateModalOpen: false,
          isTransactionCreateModalOpen: false,
          isDepositModalOpen: false,
          isWithdrawalModalOpen: false,
        });
      },
    }),
    {
      name: "banking-forms-store",
    },
  ),
);

// Sélecteurs pour optimiser les re-renders
export const useAccountCreateForm = () => useBankingFormsStore((state) => state.accountCreate);
export const useTransferCreateForm = () => useBankingFormsStore((state) => state.transferCreate);
export const useTransactionCreateForm = () => useBankingFormsStore((state) => state.transactionCreate);

export const useBankingModalsState = () =>
  useBankingFormsStore((state) => ({
    isAccountCreateModalOpen: state.isAccountCreateModalOpen,
    isTransferCreateModalOpen: state.isTransferCreateModalOpen,
    isTransactionCreateModalOpen: state.isTransactionCreateModalOpen,
    isDepositModalOpen: state.isDepositModalOpen,
    isWithdrawalModalOpen: state.isWithdrawalModalOpen,
  }));

export const useBankingFormsActions = () =>
  useBankingFormsStore((state) => ({
    // Actions formulaire compte
    updateAccountCreateForm: state.updateAccountCreateForm,
    validateAccountCreateForm: state.validateAccountCreateForm,
    resetAccountCreateForm: state.resetAccountCreateForm,
    setAccountCreateField: state.setAccountCreateField,
    touchAccountCreateField: state.touchAccountCreateField,
    setAccountCreateSubmitting: state.setAccountCreateSubmitting,

    // Actions formulaire transfert
    updateTransferCreateForm: state.updateTransferCreateForm,
    validateTransferCreateForm: state.validateTransferCreateForm,
    resetTransferCreateForm: state.resetTransferCreateForm,
    setTransferCreateField: state.setTransferCreateField,
    touchTransferCreateField: state.touchTransferCreateField,
    setTransferCreateSubmitting: state.setTransferCreateSubmitting,

    // Actions formulaire transaction
    updateTransactionCreateForm: state.updateTransactionCreateForm,
    validateTransactionCreateForm: state.validateTransactionCreateForm,
    resetTransactionCreateForm: state.resetTransactionCreateForm,
    setTransactionCreateField: state.setTransactionCreateField,
    touchTransactionCreateField: state.touchTransactionCreateField,
    setTransactionCreateSubmitting: state.setTransactionCreateSubmitting,

    // Actions modales
    openAccountCreateModal: state.openAccountCreateModal,
    closeAccountCreateModal: state.closeAccountCreateModal,
    openTransferCreateModal: state.openTransferCreateModal,
    closeTransferCreateModal: state.closeTransferCreateModal,
    openTransactionCreateModal: state.openTransactionCreateModal,
    closeTransactionCreateModal: state.closeTransactionCreateModal,
    openDepositModal: state.openDepositModal,
    closeDepositModal: state.closeDepositModal,
    openWithdrawalModal: state.openWithdrawalModal,
    closeWithdrawalModal: state.closeWithdrawalModal,

    // Actions générales
    resetAllForms: state.resetAllForms,
    closeAllModals: state.closeAllModals,
  }));
