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

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

	it("should generate methods for Ethereum with viem", () => {
		const content = generateMethodsContent([mockChains[0]], true)

		// Check for viem-specific methods
		expect(content).toContain("fetchEthereumPublicClient")
		expect(content).toContain("fetchEthereumWalletClient")
		expect(content).toContain("fetchEthereumMessage")

		// Check for proper imports
		expect(content).toContain(
			"import { isEthereumWallet } from '@dynamic-labs/ethereum'"
		)
	})

	it("should generate methods for Ethereum with ethers", () => {
		const content = generateMethodsContent([mockChains[0]], false)

		// Check for ethers-specific methods
		expect(content).toContain("fetchEthereumProvider")
		expect(content).toContain("fetchEthereumSigner")
		expect(content).toContain("fetchEthereumMessage")

		// Check for proper imports
		expect(content).toContain(
			"import { isEthereumWallet } from '@dynamic-labs/ethereum'"
		)
		expect(content).toContain(
			'import { getWeb3Provider, getSigner } from "@dynamic-labs/ethers-v6"'
		)
	})

	it("should correctly call ethers getSigner and getWeb3Provider as standalone functions", () => {
		const content = generateMethodsContent([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")'
		)
	})

	it("should generate methods for Solana", () => {
		const content = generateMethodsContent([mockChains[1]], false)

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

		// Check for proper imports
		expect(content).toContain(
			"import { isSolanaWallet } from '@dynamic-labs/solana'"
		)
	})

	it("should handle multiple chains", () => {
		const content = generateMethodsContent(mockChains, true)

		// Check for both Ethereum and Solana methods
		expect(content).toContain("fetchEthereumPublicClient")
		expect(content).toContain("fetchSolanaConnection")

		// Check for both imports
		expect(content).toContain(
			"import { isEthereumWallet } from '@dynamic-labs/ethereum'"
		)
		expect(content).toContain(
			"import { isSolanaWallet } from '@dynamic-labs/solana'"
		)
	})

	it("should include error handling", () => {
		const content = generateMethodsContent([mockChains[0]], true)

		// Check for try/catch blocks
		expect(content).toContain("try {")
		expect(content).toContain("catch (error) {")
		expect(content).toContain("setResult(safeStringify({ error:")
	})

	it("should include loading state management", () => {
		const content = generateMethodsContent([mockChains[0]], true)

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