// store.ts
import axios from "axios"
import { ConsoleKit } from "brahma-console-kit"
import { toast } from "react-toastify"
import { encodePacked, fromHex, WalletClient } from "viem"
import { base } from "viem/chains"
import { create } from "zustand"
import Safe from "@safe-global/protocol-kit"
import { signTypedData, waitForTransactionReceipt } from "@wagmi/core"

import withdrawAbi from "@/components/shared/abi/withdrawContractAbi.json"
import { BASE_CHAIN_ID, URL_API_KEY_PROD } from "@/constants"
import { SupportedChainIds, TAsset } from "@/types"
import {
  fetchAndFilterAssetBalances,
  formatRejectMetamaskErrorMessage,
  truncateString,
} from "@/utils"
import { baseWagmiConfig as wagmiConfig } from "@/wagmi"
import { PROD_URL } from "../morphoStrategy/constants"
import { dispatchToast } from "../shared/components"
import localStorageService from "../shared/services/localStoage"
import useConfigStore from "../shared/store"
import { Address } from "../shared/types"
import { INITIAL_AUTOMATION_DATA } from "./constants"
import {
  AutomationAgent,
  AutomationAgentData,
  AutomationAgentMetadata,
  AutomationAgentSubscription,
  NewSwapAgentStep,
  SwapAgentTab,
} from "./types"
import { isOneToOneSafe } from "./utils"

// const HARDCODED_REGISTRY_ID_DEV = "f2bc4f31-e837-4c94-8ef8-73b4535191dd"
const HARDCODED_REGISTRY_ID_PROD = "ae40c25f-6292-4028-9753-04cc9459e298"
const HARDCODED_REGISTRY_ID = HARDCODED_REGISTRY_ID_PROD

const API_URL = PROD_URL
const API_KEY = URL_API_KEY_PROD

// const API_URL = DEV_URL
// const API_KEY = URL_API_KEY_DEV
const kit = new ConsoleKit(API_KEY, API_URL)

const stepOrder: NewSwapAgentStep[] = [
  "SELECT_AGENT",
  "LOADING_SELECT_AGENT_ANIMATION",
  "ONE",
  "TWO",
  "THREE",
  "FOUR",
  "RUNNING",
]

type SwapAgentStore = {
  automations: {
    activeAutomations: AutomationAgentSubscription[]
    historyAutomations: AutomationAgentSubscription[]
    loading: boolean
  }
  existingSafeAddress: Address | null
  currentStep: NewSwapAgentStep
  currentTab: SwapAgentTab
  selectedAgent: AutomationAgent
  automationAgentData: Record<AutomationAgent, AutomationAgentData>
  eoaBalances: {
    data: TAsset[]
    loading: boolean
  }
  balances: {
    data: TAsset[]
    loading: boolean
  }
  preComputedConsoleAddress: Address | null
  feeEstimateSignature: string | null
  feeEstimate: string | null

  permissionModalData: {
    isShowingModal: boolean
    state: "PENDING" | "SUCCESS"
  }

  isWithdrawLoading: boolean

  fetchEoaAssets: (eoa: Address, assets: TAsset[]) => Promise<void>
  setCurrentTab: (tab: SwapAgentTab) => void
  setCurrentStep: (step: NewSwapAgentStep) => void
  setSelectedAgent: (agent: AutomationAgent) => void
  goToNextStep: () => void
  goToPreviousStep: () => void
  updateAgentData: (
    agent: AutomationAgent,
    state: Partial<AutomationAgentData>,
  ) => void
  resetAgentsData: () => void

  fetchPreComputedConsoleAddress: (
    owner: Address,
    chainId: SupportedChainIds,
    feeToken: Address,
  ) => Promise<void>
  withdrawAmount: (
    eoa: Address,
    signer: WalletClient,
    subAccountAddress: Address,
    consoleAddress: Address,
    targetToken: TAsset,
    allocatedToken: TAsset,
    closeExitModal?: () => void,
  ) => Promise<void>
  subscribeToAutomationWithExistingConsole: (
    eoa: Address,
    signer: WalletClient,
    chainId: SupportedChainIds,
    tokenInputs: Record<Address, string>,
    tokenLimits: Record<Address, string>,
    metadata: AutomationAgentMetadata,
    existingConsoleAddress: Address,
    setConsoleDeployedLoading: React.Dispatch<React.SetStateAction<boolean>>,
  ) => Promise<void>
  fetchExistingSwapAgentConsole: (eoa: Address) => Promise<void>
  generateAndDeploySubAccount: (
    eoa: Address,
    chainId: SupportedChainIds,
    feeToken: Address,
    feeEstimate: string,
    tokens: Address[],
    amounts: string[],
    tokenInputs: Record<Address, string>,
    tokenLimits: Record<Address, string>,
    metadata: AutomationAgentMetadata,
  ) => Promise<{
    taskId: string
  } | null>
  fetchConsoleBalances: (
    assets: TAsset[],
    consoleAddress: Address,
    addressToDetect?: Address,
  ) => Promise<boolean>
  fetchAutomations: (eoa: Address, showLoading?: boolean) => Promise<void>
  pollTaskStatus(taskId: string): Promise<string | undefined>
  createTransactionEntry(
    txnHash: string,
    chainId: SupportedChainIds,
  ): Promise<void>
  updatePermissionModalData: (
    state: Partial<SwapAgentStore["permissionModalData"]>,
  ) => void
  setExistingSafeAddress: (safeAddress: Address) => void
}

const useAutomationAgentStore = create<SwapAgentStore>((set, get) => ({
  existingSafeAddress: null,
  automations: {
    activeAutomations: [],
    historyAutomations: [],
    loading: false,
  },
  currentStep: "SELECT_AGENT",
  currentTab: SwapAgentTab.NEW_AGENT,
  selectedAgent: "SURGE",
  automationAgentData: INITIAL_AUTOMATION_DATA,
  permissionModalData: {
    isShowingModal: false,
    state: "PENDING",
  },
  isWithdrawLoading: false,
  eoaBalances: {
    data: [],
    loading: false,
  },
  balances: {
    data: [],
    loading: false,
  },
  preComputedConsoleAddress: null,
  feeEstimate: null,
  feeEstimateSignature: null,

  setExistingSafeAddress: (safeAddress) => {
    set({ existingSafeAddress: safeAddress })
  },

  updatePermissionModalData: (
    updatedState: Partial<SwapAgentStore["permissionModalData"]>,
  ) => {
    set((state) => ({
      permissionModalData: { ...state.permissionModalData, ...updatedState },
    }))
  },

  setCurrentTab: (tab: SwapAgentTab) => {
    set({ currentTab: tab })
  },

  setCurrentStep: (step: NewSwapAgentStep) => {
    set({ currentStep: step })
  },

  setSelectedAgent: (agent: AutomationAgent) => {
    set({ selectedAgent: agent })
  },

  goToNextStep: () => {
    const currentStep = get().currentStep
    const currentIndex = stepOrder.indexOf(currentStep)
    if (currentIndex < stepOrder.length - 1) {
      set({ currentStep: stepOrder[currentIndex + 1] })
    }
  },

  goToPreviousStep: () => {
    const currentStep = get().currentStep
    const currentIndex = stepOrder.indexOf(currentStep)

    if (currentStep === "ONE") {
      set({ currentStep: "SELECT_AGENT" })
      return
    }

    if (currentIndex > 0) {
      set({ currentStep: stepOrder[currentIndex - 1] })
    }
  },

  updateAgentData: (
    agent: AutomationAgent,
    state: Partial<AutomationAgentData>,
  ) => {
    const { automationAgentData } = get()
    const updatedAgentState = { ...automationAgentData[agent], ...state }
    set((prev) => ({
      automationAgentData: {
        ...prev.automationAgentData,
        [agent]: updatedAgentState,
      },
    }))
  },

  fetchEoaAssets: async (eoa, assets) => {
    try {
      const filteredUserAssets = await fetchAndFilterAssetBalances(eoa, assets)

      set({
        eoaBalances: {
          data: filteredUserAssets,
          loading: false,
        },
      })
    } catch (err) {
      console.error("error on fetching eoa assets", err)
    }
  },

  resetAgentsData: () => {
    set({
      automationAgentData: INITIAL_AUTOMATION_DATA,
      currentStep: "SELECT_AGENT",
      existingSafeAddress: null,
      currentTab: SwapAgentTab.NEW_AGENT,
      automations: {
        activeAutomations: [],
        historyAutomations: [],
        loading: false,
      },
      eoaBalances: {
        data: [],
        loading: false,
      },
      balances: {
        data: [],
        loading: false,
      },
      preComputedConsoleAddress: null,
    })
  },

  fetchPreComputedConsoleAddress: async (owner, chainId, feeToken) => {
    set((state) => ({ ...state, loading: true }))
    try {
      const data = await kit.publicDeployer.fetchPreComputeData(
        owner,
        chainId,
        feeToken,
      )

      if (
        !data ||
        !data.feeEstimate ||
        !data.feeEstimateSignature ||
        !data.precomputedAddress
      ) {
        throw new Error("Invalid data received from fetchPreComputeAddress")
      }

      set((state) => ({
        ...state,
        loading: false,
        feeEstimate: data.feeEstimate,
        feeEstimateSignature: data.feeEstimateSignature,
        preComputedConsoleAddress: data.precomputedAddress,
      }))
    } catch (err: any) {
      console.log(`Error fetching precompute address: ${err}`)
      dispatchToast({
        id: "fetch-precompute-address-error",
        title: "Error fetching precompute address",
        description: {
          value:
            err?.message ||
            "An error occurred while fetching precompute address",
        },
        type: "error",
      })
      set((state) => ({ ...state, loading: false })) // Ensure loading is set to false on error
    }
  },

  withdrawAmount: async (
    eoa,
    signer,
    subAccountAddress,
    consoleAddress,
    targetToken,
    allocatedToken,
    closeExitModal,
  ) => {
    const { createTransactionEntry, fetchAutomations } = get()

    set({ isWithdrawLoading: true })
    dispatchToast({
      id: "withdraw-start",
      type: "loading",
      title: "Transaction in progress",
      description: {
        value:
          "Cancelling agent transaction and withdrawing funds. Please wait...",
      },
      toastOptions: {
        autoClose: false,
      },
    })

    try {
      console.log(
        "[Withdraw] Step 1: Initiating cancellation with console kit...",
      )
      const response = await kit.automationContext.cancelAutomation({
        chainId: BASE_CHAIN_ID,
        subAccountAddress,
        data: {
          ownerConsole: consoleAddress,
          sweepTokens: [targetToken.address, allocatedToken.address],
          execViaSubAcc: [],
          sweepTokenReceiver: eoa,
        },
      })
      console.log(
        "[Withdraw] Step 1 Complete: Agent transaction cancelled successfully",
        response,
      )

      console.log("[Withdraw] Step 2: Initializing Safe transaction...")
      const safe = await Safe.init({
        provider:
          "https://base-mainnet.g.alchemy.com/v2/q2VDjsGh2h0P6WZSXUq2eTw7y0_Ffkdq",
        safeAddress: consoleAddress,
      })

      const transaction = await safe.createTransaction({
        transactions: response.data.transactions,
        onlyCalls: false,
      })

      const {
        baseGas,
        data,
        gasPrice,
        gasToken,
        operation,
        refundReceiver,
        safeTxGas,
        to,
        value,
      } = transaction.data

      console.log("[Withdraw] Step 3: Generating transaction signature...")
      const signature = encodePacked(
        ["bytes12", "address", "bytes32", "bytes1"],
        [
          "0x000000000000000000000000",
          eoa,
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x01",
        ],
      )

      console.log("[Withdraw] Step 4: Executing transaction on Safe...")
      const txnHash = await signer.writeContract({
        chain: base,
        address: consoleAddress,
        abi: withdrawAbi,
        functionName: "execTransaction",
        account: eoa,
        gas: BigInt(2000000),
        args: [
          to,
          value,
          data,
          operation,
          safeTxGas,
          baseGas,
          gasPrice,
          gasToken,
          refundReceiver,
          signature,
        ],
      })

      if (!txnHash) throw new Error("execTransaction failed")
      console.log(`[Withdraw] Step 5: Transaction sent with hash: ${txnHash}`)

      console.log("[Withdraw] Step 6: Waiting for transaction receipt...")
      await waitForTransactionReceipt(wagmiConfig, { hash: txnHash })

      console.log("[Withdraw] Step 7: Storing transaction entry...")
      await createTransactionEntry(txnHash, BASE_CHAIN_ID)

      console.log("[Withdraw] Step 8: Refreshing agent data...")
      fetchAutomations(eoa)

      dispatchToast({
        id: "withdraw-success",
        type: "success",
        title: "Withdrawal Successful",
        description: {
          value: `Transaction completed successfully! Hash: ${truncateString(txnHash, 10)}`,
        },
      })

      closeExitModal && setTimeout(closeExitModal, 1000)
    } catch (err: any) {
      console.error("[Withdraw] Error occurred:", err)
      dispatchToast({
        id: "withdraw-failed",
        type: "error",
        title: "Transaction Failed",
        description: {
          value:
            formatRejectMetamaskErrorMessage(err) ||
            err?.shortMessage ||
            err?.message ||
            "Something went wrong. Please try again.",
        },
      })
    } finally {
      toast.dismiss("withdraw-start")
      set({ isWithdrawLoading: false })
    }
  },

  subscribeToAutomationWithExistingConsole: async (
    eoa,
    signer,
    chainId,
    tokenInputs,
    tokenLimits,
    metadata,
    existingConsoleAddress,
    setConsoleDeployedLoading,
  ) => {
    const {
      createTransactionEntry,
      fetchAutomations,
      updatePermissionModalData,
      goToNextStep,
    } = get()

    if (!signer?.account) {
      dispatchToast({
        id: "error-missing-wallet",
        type: "error",
        title: "Wallet not connected",
        description: { value: "Please connect your wallet and try again." },
      })
      return
    }

    setConsoleDeployedLoading(true)
    updatePermissionModalData({ isShowingModal: true, state: "PENDING" })

    dispatchToast({
      id: "subscribe-start",
      type: "loading",
      title: "Transaction in progress",
      description: { value: "Subscribing to agent. Please wait..." },
      toastOptions: { autoClose: false },
    })

    try {
      console.log(
        "[Subscribe] Step 1: Initiating subscription with console kit...",
      )
      const response = await kit.automationContext.subscribeToAutomation({
        data: {
          metadata,
          tokenInputs,
          tokenLimits,
          registryID: HARDCODED_REGISTRY_ID,
          chainId,
          ownerAddress: existingConsoleAddress,
          duration: 0,
          whitelistedAddresses: [eoa],
        },
        chainId,
      })
      console.log(
        "[Subscribe] Step 1 Complete: Subscription initialized",
        response,
      )

      console.log("[Subscribe] Step 2: Initializing Safe transaction...")
      const safe = await Safe.init({
        provider:
          "https://base-mainnet.g.alchemy.com/v2/q2VDjsGh2h0P6WZSXUq2eTw7y0_Ffkdq",
        safeAddress: existingConsoleAddress,
      })

      const transaction = await safe.createTransaction({
        transactions: response.data.transactions,
        onlyCalls: false,
      })

      const {
        baseGas,
        data,
        gasPrice,
        gasToken,
        operation,
        refundReceiver,
        safeTxGas,
        to,
        value,
      } = transaction.data

      console.log("[Subscribe] Step 3: Generating transaction signature...")
      const signature = encodePacked(
        ["bytes12", "address", "bytes32", "bytes1"],
        [
          "0x000000000000000000000000", // Placeholder
          eoa,
          "0x0000000000000000000000000000000000000000000000000000000000000000", // Placeholder
          "0x01", // Placeholder
        ],
      )

      console.log("[Subscribe] Step 4: Executing transaction on Safe...")
      const txnHash = await signer.writeContract({
        chain: base,
        address: existingConsoleAddress,
        abi: withdrawAbi,
        functionName: "execTransaction",
        account: eoa,
        gas: BigInt(2000000),
        args: [
          to,
          value,
          data,
          operation,
          safeTxGas,
          baseGas,
          gasPrice,
          gasToken,
          refundReceiver,
          signature,
        ],
      })

      if (!txnHash) throw new Error("execTransaction failed")
      console.log(`[Subscribe] Step 5: Transaction sent with hash: ${txnHash}`)

      console.log("[Subscribe] Step 6: Waiting for transaction receipt...")
      await waitForTransactionReceipt(wagmiConfig, { hash: txnHash as Address })

      console.log("[Subscribe] Step 7: Storing transaction entry...")
      await createTransactionEntry(txnHash, BASE_CHAIN_ID)

      console.log("[Subscribe] Step 8: Updating permission modal data...")
      updatePermissionModalData({ isShowingModal: true, state: "SUCCESS" })

      console.log("[Subscribe] Step 9: Moving to the next step...")
      goToNextStep()

      await new Promise((resolve) => setTimeout(resolve, 3000))

      console.log("[Subscribe] Step 10: Refreshing agent data...")
      fetchAutomations(eoa)

      dispatchToast({
        id: "subscribe-success",
        type: "success",
        title: "Subscription Successful",
        description: {
          value: `Subscription completed successfully! Hash: ${truncateString(txnHash, 10)}`,
        },
      })
    } catch (err: any) {
      console.error("[Subscribe] Error occurred:", err)

      dispatchToast({
        id: "subscribe-failed",
        type: "error",
        title: "Setup Failed",
        description: {
          value:
            formatRejectMetamaskErrorMessage(err) ||
            err?.shortMessage ||
            err?.message ||
            "Failed to deploy agent account",
        },
      })

      updatePermissionModalData({ isShowingModal: false })
    } finally {
      toast.dismiss("subscribe-start")
      setConsoleDeployedLoading(false)
    }
  },

  generateAndDeploySubAccount: async (
    eoa,
    chainId,
    feeToken,
    feeEstimate,
    tokens,
    amounts,
    tokenInputs,
    tokenLimits,
    metadata,
  ) => {
    const { preComputedConsoleAddress, feeEstimateSignature } = get()

    if (!preComputedConsoleAddress) {
      dispatchToast({
        id: "fetch-precomputed-account-address-error",
        title: "Error fetching precomputed account address",
        description: {
          value: "Precomputed account address not found",
        },
        type: "error",
      })
      return null
    }

    set((state) => ({ ...state, loading: true }))
    try {
      const generateData =
        await kit.publicDeployer.generateAutomationSubAccount(
          eoa,
          preComputedConsoleAddress,
          chainId,
          HARDCODED_REGISTRY_ID,
          feeToken,
          feeEstimate,
          tokens,
          amounts,
          {
            duration: 0,
            tokenInputs: tokenInputs,
            tokenLimits: tokenLimits,
            whitelistedAddresses: [eoa],
          },
          metadata,
        )

      if (!generateData || !feeEstimateSignature) {
        dispatchToast({
          id: "fetch-signature-error",
          title: "Error fetching signature",
          description: {
            value: "An error occurred while fetching signature",
          },
          type: "error",
        })
        return null
      }

      const {
        signaturePayload: { domain, message, types, primaryType },
        subAccountPolicyCommit,
        subscriptionDraftID,
      } = generateData

      const signature = await signTypedData(wagmiConfig, {
        domain: {
          verifyingContract: domain.verifyingContract,
          chainId: fromHex(domain.chainId as Address, "number"),
        },
        types,
        primaryType,
        message,
      })

      if (!signature) {
        dispatchToast({
          id: "upgrade-console-error",
          type: "error",
          title: "Error",
          description: {
            value: "User rejected the transaction",
          },
        })
        return null
      }

      // Deploy Brahma Account
      const deployData = await kit.publicDeployer.deployBrahmaAccount(
        eoa,
        chainId,
        HARDCODED_REGISTRY_ID,
        subscriptionDraftID,
        subAccountPolicyCommit,
        feeToken,
        tokens,
        amounts,
        signature, // Use the signature obtained from the previous step
        feeEstimateSignature,
        feeEstimate,
        {},
      )

      if (!deployData) {
        dispatchToast({
          id: "deploy-account-error",
          title: "Error deploying account and sub-account",
          description: {
            value: "An error occurred during deployment",
          },
          type: "error",
        })
        return null
      }

      // Update state with taskId and set loading to false
      set((state) => ({
        ...state,
        signature, // Update the state with the signature
        loading: false,
      }))

      return deployData
    } catch (err: any) {
      console.error("Error in generate and deploy sub-account:", err)
      dispatchToast({
        id: "generate-deploy-error",
        title: "Error in generate and deploy sub-account",
        description: {
          value: err?.message || "An error occurred during the process",
        },
        type: "error",
      })
      return null
    }
  },

  fetchConsoleBalances: async (assets, consoleAddress, addressToDetect) => {
    if (!consoleAddress) {
      dispatchToast({
        id: "fetch-precomputed-account-balances-error",
        title: "Error fetching balances",
        description: {
          value: "Console address not found",
        },
        type: "error",
      })
      return false
    }

    set((state) => ({ balances: { ...state.balances, loading: true } }))

    try {
      const filteredUserAssets = await fetchAndFilterAssetBalances(
        consoleAddress,
        assets,
      )

      set({
        balances: {
          data: filteredUserAssets,
          loading: false,
        },
      })

      if (!addressToDetect) {
        return false
      }

      const targetToken = filteredUserAssets.find(
        (asset) =>
          asset.address.toLowerCase() === addressToDetect.toLowerCase(),
      )

      if (!targetToken) {
        return false
      }

      const targetTokenHasAmount = targetToken?.balanceOf?.value !== BigInt(0)

      return targetTokenHasAmount
    } catch (err) {
      console.error("Error fetching precomputed console balances:", err)
      set((state) => ({ balances: { ...state.balances, loading: false } }))
      return false
    }
  },

  fetchExistingSwapAgentConsole: async (eoa: Address) => {
    try {
      // Check if we already have a 1:1 safe in local storage
      const existingSafeAddress =
        localStorageService.getDeployedSwapAgentConsole()
      if (existingSafeAddress) {
        console.log("Using 1:1 Safe from local storage:", existingSafeAddress)
        set({
          existingSafeAddress: existingSafeAddress as Address,
        })
        return
      }

      const eoaAccounts = await kit.coreActions.fetchExistingAccounts(eoa)

      if (!eoaAccounts.length) return

      const filteredEoaAccountsForBaseChainId = eoaAccounts.filter(
        (account) => account.chainId === BASE_CHAIN_ID,
      )

      for (const account of filteredEoaAccountsForBaseChainId) {
        try {
          if (!account) continue

          const isSafe = await isOneToOneSafe(account.consoleAddress)

          if (isSafe) {
            console.log("Found 1:1 Safe:", account.consoleAddress)
            localStorageService.setDeployedSwapAgentConsole(
              account.consoleAddress,
            ) // Store in local storage
            set({ existingSafeAddress: account.consoleAddress }) // Update state with the found address
            return // Exit the loop after finding the first 1:1 Safe
          }
        } catch (error) {
          console.error(
            `Error checking ${account.consoleAddress} or setting local storage:`,
            error,
          )
        }
      }

      // If no 1:1 Safe is found, clear the local storage (optional)
      localStorageService.clearDeployedSwapAgentConsole()
      set({ existingSafeAddress: null }) // No 1:1 Safe found, update state accordingly
    } catch (error) {
      console.error("Error fetching 1:1 Safes:", error)
      set({ existingSafeAddress: null })
    }
  },

  fetchAutomations: async (eoa, showLoading = true) => {
    const { fetchAndAddToConfig, assets } = useConfigStore.getState()
    if (showLoading) {
      set((state) => ({
        ...state,
        automations: { ...state.automations, loading: true },
      }))
    }

    try {
      const { data } = await axios.get(
        `${API_URL}/automations/subscriptions/owner/${eoa}/${HARDCODED_REGISTRY_ID}`,
        {
          headers: {
            "x-api-key": API_KEY,
          },
        },
      )

      const currentAccountAutomations: AutomationAgentSubscription[] =
        data?.data

      const allTokens = currentAccountAutomations.flatMap(({ metadata }) => [
        metadata.sellToken,
        metadata.buyToken,
      ]) as Address[]

      const tokensNotInMetadata = allTokens.filter(
        (token) =>
          !assets.some(
            (asset) => asset.address.toLowerCase() === token.toLowerCase(),
          ),
      )
      await fetchAndAddToConfig(tokensNotInMetadata)

      const activeAutomations: AutomationAgentSubscription[] =
        currentAccountAutomations.filter(
          (automation) =>
            automation.registryId.toLowerCase() ===
              (HARDCODED_REGISTRY_ID || "").toLowerCase() &&
            automation.status === 2,
        )

      const historyAutomations: AutomationAgentSubscription[] =
        currentAccountAutomations.filter(
          (automation) =>
            automation.registryId.toLowerCase() ===
              (HARDCODED_REGISTRY_ID || "").toLowerCase() &&
            automation.status === 4,
        )

      set((prev) => ({
        automations: {
          ...prev.automations,
          activeAutomations,
          historyAutomations,
        },
      }))
    } catch (error) {
      console.error("Error in fetchAutomations:", error)
    } finally {
      set((state) => ({
        ...state,
        automations: { ...state.automations, loading: false },
      }))
    }
  },

  async pollTaskStatus(taskId) {
    const POLLING_INTERVAL = 5000
    const MAX_ATTEMPTS = 20
    let attempts = 0

    return new Promise((resolve, reject) => {
      const poll = async () => {
        try {
          try {
            const response =
              await kit.publicDeployer.fetchDeploymentStatus(taskId)

            // Check if response or data is empty
            if (!response || !response.outputTransactionHash) {
              attempts++
              if (attempts >= MAX_ATTEMPTS) {
                reject(new Error("Polling timeout exceeded"))
                return ""
              }
              setTimeout(poll, POLLING_INTERVAL)
              return ""
            }

            if (response.status === "successful") {
              resolve(response.outputTransactionHash)
              return
            }

            attempts++
            if (attempts >= MAX_ATTEMPTS) {
              reject(new Error("Polling timeout exceeded"))
              return ""
            }

            setTimeout(poll, POLLING_INTERVAL)
          } catch (error) {
            console.error("Error fetching task status:", error)
            attempts++
            if (attempts >= MAX_ATTEMPTS) {
              reject(new Error("Polling timeout exceeded"))
              return ""
            }
            setTimeout(poll, POLLING_INTERVAL)
          }
        } catch (error) {
          console.error("Unexpected error in poll:", error)
          attempts++
          if (attempts >= MAX_ATTEMPTS) {
            reject(new Error("Polling timeout exceeded"))
            return ""
          }
          setTimeout(poll, POLLING_INTERVAL)
        }
      }

      poll()
    })
  },

  async createTransactionEntry(txnHash, chainId) {
    try {
      await kit.coreActions.indexTransaction(txnHash, chainId)
    } catch (error) {
      dispatchToast({
        id: "indexer-error",
        title: "Error",
        description: {
          value:
            error instanceof Error
              ? error.message
              : "Failed to process transaction",
        },
        type: "error",
      })
    }
  },
}))

export default useAutomationAgentStore
