import { describe, it, expect } from "bun:test"
import { generateMethodsTsxContent } from "../../../react-templates/methods"
import type { Chain } from "../../../types"

describe("React Method Generation", () => {
	const mockChains: Chain[] = [
		{
			name: "Ethereum",
			package: "@dynamic-labs/ethereum",
			connector: "EthereumWalletConnectors",
		},
	]

	describe("Ethereum with Viem", () => {
		it("should generate correct method imports", () => {
			const content = generateMethodsTsxContent([mockChains[0]], true)

			// Check for core imports
			expect(content).toContain("import { useState, useEffect } from 'react'")
			expect(content).toContain(
				'import { useDynamicContext, useIsLoggedIn, useUserWallets } from "@dynamic-labs/sdk-react-core"'
			)
			expect(content).toContain(
				"import { isEthereumWallet } from '@dynamic-labs/ethereum'"
			)
			expect(content).toContain("import './Methods.css'")

			// Check for chain-specific imports
			expect(content).not.toContain("import { SolanaWalletConnectors }")
		})

		it("should generate correct method implementations", () => {
			const content = generateMethodsTsxContent([mockChains[0]], true)

			// Check for method implementations
			expect(content).toContain("fetchEthereumPublicClient")
			expect(content).toContain("fetchEthereumWalletClient")
			expect(content).toContain("fetchEthereumMessage")
		})
	})

	describe("Ethereum with Ethers", () => {
		it("should generate correct method imports", () => {
			const content = generateMethodsTsxContent([mockChains[0]], false)

			// Check for core imports
			expect(content).toContain("import { useState, useEffect } from 'react'")
			expect(content).toContain(
				'import { useDynamicContext, useIsLoggedIn, useUserWallets } from "@dynamic-labs/sdk-react-core"'
			)
			expect(content).toContain(
				"import { isEthereumWallet } from '@dynamic-labs/ethereum'"
			)
			expect(content).toContain(
				'import { getWeb3Provider, getSigner } from "@dynamic-labs/ethers-v6"'
			)
			expect(content).toContain("import './Methods.css'")

			// Check for chain-specific imports
			expect(content).not.toContain("import { SolanaWalletConnectors }")
		})

		it("should generate correct method implementations", () => {
			const content = generateMethodsTsxContent([mockChains[0]], false)

			// Check for method implementations
			expect(content).toContain("fetchEthereumProvider")
			expect(content).toContain("fetchEthereumSigner")
			expect(content).toContain("fetchEthereumMessage")
		})

		it("should correctly call ethers getSigner and getWeb3Provider as standalone functions", () => {
			const content = generateMethodsTsxContent([mockChains[0]], false)

			// Check that getSigner and getWeb3Provider are called as standalone functions with the wallet as an argument
			expect(content).toContain("const result = await getSigner(primaryWallet)")
			expect(content).toContain(
				"const result = await getWeb3Provider(primaryWallet)"
			)

			// Verify the signMessage is still called as a method on the wallet
			expect(content).toContain(
				'const result = await primaryWallet.signMessage("Hello World")'
			)
		})
	})

	describe("Multiple Chains", () => {
		const mockChainsMultiple: Chain[] = [
			...mockChains,
			{
				name: "Solana",
				package: "@dynamic-labs/solana",
				connector: "SolanaWalletConnectors",
			},
		]

		it("should generate methods for all configured chains", () => {
			const content = generateMethodsTsxContent(mockChainsMultiple, true)

			// Check for Ethereum methods
			expect(content).toContain("fetchEthereumPublicClient")
			expect(content).toContain("fetchEthereumWalletClient")

			// Check for Solana methods
			expect(content).toContain("fetchSolanaConnection")
			expect(content).toContain("fetchSolanaSigner")
		})

		it("should include proper error handling", () => {
			const content = generateMethodsTsxContent(mockChainsMultiple, true)

			// Check for error handling
			expect(content).toContain("try {")
			expect(content).toContain("catch (error) {")
			expect(content).toContain("setError")
		})

		it("should include loading state management", () => {
			const content = generateMethodsTsxContent(mockChainsMultiple, true)

			// Check for loading state
			expect(content).toContain("setIsLoading(true)")
			expect(content).toContain("setIsLoading(false)")
		})
	})
})
