/**
 * VaultfireAgentSDK — Standalone TypeScript SDK for the Vaultfire Agent Trust Protocol
 *
 * No Next.js dependencies. Works in any Node.js or browser environment.
 * All read operations call the Vaultfire Agent API (no direct RPC needed).
 * All write operations return unsigned transaction data for the caller to sign.
 *
 * @module VaultfireAgentSDK
 */

/* ═══════════════════════════════════════════════════════
   TYPES
   ═══════════════════════════════════════════════════════ */

export type SupportedChain = 'base' | 'avalanche' | 'ethereum';
export type AgentType = 'autonomous' | 'assistant' | 'specialized' | 'multi-agent';
export type BondTier = 'bronze' | 'silver' | 'gold' | 'platinum';
export type AttestationType = 'action' | 'claim' | 'decision' | 'refusal';
export type TrustGrade = 'A' | 'B' | 'C' | 'D' | 'F' | 'Unverified';
export type ReputationTier = 'unverified' | 'bronze' | 'silver' | 'gold' | 'platinum';
export type AgentBondType = 'collaboration' | 'oversight' | 'delegation' | 'peer';

export interface TrustProfile {
  address: string;
  chain: string;
  isRegistered: boolean;
  isBonded: boolean;
  reputationScore: number;
  reputationTier: ReputationTier;
  endorsements: number;
  violations: number;
  bondAmount: string;
  bondPartner: string | null;
  vnsName: string | null;
  lastActivity: number;
  trustGrade: TrustGrade;
  verificationUrl: string;
}

export interface ReputationData {
  address: string;
  chain: string;
  score: number;
  tier: ReputationTier;
  endorsements: number;
  violations: number;
  lastActivity: number;
  history: AccountabilityRecord[];
}

export interface BondStatus {
  hasBond: boolean;
  tier: BondTier | null;
  bondAmountWei: string;
  bondAmountEth: number;
  partnerAddress: string | null;
  bondType: string | null;
  isActive: boolean;
  createdAt: number;
}

export interface AccountabilityRecord {
  timestamp: number;
  type: 'endorsement' | 'violation' | 'attestation' | 'bond_created' | 'bond_upgraded';
  description: string;
  txHash: string;
  impact: number;
}

export interface FlourishingData {
  address: string;
  chain: string;
  autonomy: number;
  privacy: number;
  connection: number;
  growth: number;
  wellbeing: number;
  overallScore: number;
  lastUpdated: number;
}

export interface TransactionData {
  to: string;
  data: string;
  value: string;
  chainId: number;
  gasEstimate: string;
}

export interface RegisterAgentParams {
  name: string;
  agentType: AgentType;
  operator: string;
  capabilities?: string[];
  chain: SupportedChain;
}

export interface CreateBondParams {
  agentAddress: string;
  partnerAddress: string;
  bondType?: AgentBondType;
  bondTier?: BondTier;
  chain: SupportedChain;
}

export interface AttestParams {
  agentAddress: string;
  attestationType: AttestationType;
  content: string;
  confidence?: number;
  chain: SupportedChain;
}

export interface SDKConfig {
  chain: SupportedChain;
  rpcUrl?: string;
  apiKey?: string;
  apiBase?: string;
}

interface ApiResponse<T> {
  success: boolean;
  data?: T;
  error?: string;
  requestId?: string;
}

/* ═══════════════════════════════════════════════════════
   CONSTANTS
   ═══════════════════════════════════════════════════════ */

export const VAULTFIRE_CHAINS: Record<SupportedChain, { chainId: number; name: string; explorer: string }> = {
  base: { chainId: 8453, name: 'Base', explorer: 'https://basescan.org' },
  avalanche: { chainId: 43114, name: 'Avalanche C-Chain', explorer: 'https://snowtrace.io' },
  ethereum: { chainId: 1, name: 'Ethereum Mainnet', explorer: 'https://etherscan.io' },
};

export const TRUST_TIERS: Record<BondTier, { label: string; minEth: number; color: string }> = {
  bronze: { label: 'Bronze', minEth: 0.01, color: '#d97706' },
  silver: { label: 'Silver', minEth: 0.05, color: '#9ca3af' },
  gold: { label: 'Gold', minEth: 0.1, color: '#fbbf24' },
  platinum: { label: 'Platinum', minEth: 0.5, color: '#e5e7eb' },
};

export const BOND_TYPES: Record<AgentBondType, { label: string; description: string }> = {
  collaboration: { label: 'Collaboration', description: 'Two agents working together as equals toward a shared goal' },
  oversight: { label: 'Oversight', description: 'One agent monitors and validates the actions of another' },
  delegation: { label: 'Delegation', description: 'One agent delegates specific tasks to another with accountability' },
  peer: { label: 'Peer', description: 'Symmetric trust relationship between agents of similar capability' },
};

const DEFAULT_API_BASE = 'https://theloopbreaker.com';

/* ═══════════════════════════════════════════════════════
   SDK CLASS
   ═══════════════════════════════════════════════════════ */

export class VaultfireAgentSDK {
  private chain: SupportedChain;
  private apiBase: string;
  private apiKey: string | undefined;

  constructor(config: SDKConfig) {
    this.chain = config.chain;
    this.apiBase = (config.apiBase || DEFAULT_API_BASE).replace(/\/+$/, '');
    this.apiKey = config.apiKey;
  }

  /* ──────────────────────────────────────────────────────
     PRIVATE HELPERS
     ────────────────────────────────────────────────────── */

  private headers(): Record<string, string> {
    const h: Record<string, string> = { 'Content-Type': 'application/json' };
    if (this.apiKey) h['X-API-Key'] = this.apiKey;
    return h;
  }

  private async post<T>(path: string, body: Record<string, unknown>): Promise<T> {
    const url = `${this.apiBase}${path}`;
    const res = await fetch(url, {
      method: 'POST',
      headers: this.headers(),
      body: JSON.stringify(body),
    });
    if (!res.ok) {
      const err = await res.json().catch(() => ({ error: res.statusText }));
      throw new Error((err as ApiResponse<unknown>).error || `API error ${res.status}`);
    }
    const json = (await res.json()) as ApiResponse<T>;
    if (!json.success) throw new Error(json.error || 'API returned unsuccessful response');
    return json.data as T;
  }

  private async get<T>(path: string): Promise<T> {
    const url = `${this.apiBase}${path}`;
    const res = await fetch(url, { method: 'GET', headers: this.headers() });
    if (!res.ok) {
      const err = await res.json().catch(() => ({ error: res.statusText }));
      throw new Error((err as ApiResponse<unknown>).error || `API error ${res.status}`);
    }
    const json = (await res.json()) as ApiResponse<T>;
    if (!json.success) throw new Error(json.error || 'API returned unsuccessful response');
    return json.data as T;
  }

  /* ──────────────────────────────────────────────────────
     READ OPERATIONS — call the Vaultfire Agent API
     ────────────────────────────────────────────────────── */

  /** Verify the full trust profile of any address */
  async verifyTrust(address: string): Promise<TrustProfile> {
    return this.post<TrustProfile>('/api/agent/v1/verify', {
      address,
      chain: this.chain,
    });
  }

  /** Get reputation score and history for an address */
  async getReputation(address: string): Promise<ReputationData> {
    return this.get<ReputationData>(
      `/api/agent/v1/reputation/${encodeURIComponent(address)}?chain=${this.chain}`,
    );
  }

  /** Check bond status between two addresses */
  async checkBond(agent: string, partner: string): Promise<BondStatus> {
    return this.post<BondStatus>('/api/agent/v1/bond', {
      agentAddress: agent,
      partnerAddress: partner,
      chain: this.chain,
    });
  }

  /** Look up VNS name for an address */
  async lookupVNS(address: string): Promise<string | null> {
    try {
      const result = await this.post<{ vnsName: string | null }>('/api/mcp', {
        method: 'tools/call',
        params: {
          name: 'vaultfire_lookup_vns',
          arguments: { address, chain: this.chain },
        },
        id: Date.now(),
      });
      return result?.vnsName ?? null;
    } catch {
      return null;
    }
  }

  /** Get flourishing metrics for an address */
  async getFlourishingMetrics(address: string): Promise<FlourishingData> {
    try {
      const result = await this.post<FlourishingData>('/api/mcp', {
        method: 'tools/call',
        params: {
          name: 'vaultfire_get_flourishing',
          arguments: { address, chain: this.chain },
        },
        id: Date.now(),
      });
      return result;
    } catch {
      return {
        address,
        chain: this.chain,
        autonomy: 0,
        privacy: 0,
        connection: 0,
        growth: 0,
        wellbeing: 0,
        overallScore: 0,
        lastUpdated: Date.now(),
      };
    }
  }

  /* ──────────────────────────────────────────────────────
     WRITE OPERATIONS — return unsigned transaction data
     ────────────────────────────────────────────────────── */

  /** Build a transaction to register an agent on-chain */
  async buildRegisterTx(params: RegisterAgentParams): Promise<TransactionData> {
    const result = await this.post<{ txData: TransactionData }>('/api/agent/v1/register', {
      name: params.name,
      agentType: params.agentType,
      operator: params.operator,
      capabilities: params.capabilities || [],
      chain: params.chain || this.chain,
    });
    return result.txData;
  }

  /** Build a transaction to create a partnership bond */
  async buildBondTx(params: CreateBondParams): Promise<TransactionData> {
    const result = await this.post<{ txData: TransactionData }>('/api/agent/v1/bond', {
      agentAddress: params.agentAddress,
      partnerAddress: params.partnerAddress,
      bondTier: params.bondTier || 'bronze',
      chain: params.chain || this.chain,
    });
    return result.txData;
  }

  /** Build a transaction to submit an on-chain attestation */
  async buildAttestTx(params: AttestParams): Promise<TransactionData> {
    const result = await this.post<{ txData: TransactionData }>('/api/agent/v1/attest', {
      agentAddress: params.agentAddress,
      attestationType: params.attestationType,
      content: params.content,
      confidence: params.confidence ?? 0.8,
      chain: params.chain || this.chain,
    });
    return result.txData;
  }
}

/* ═══════════════════════════════════════════════════════
   FACTORY
   ═══════════════════════════════════════════════════════ */

/** Create a new VaultfireAgentSDK instance with the given config */
export function createVaultfireSDK(config: SDKConfig): VaultfireAgentSDK {
  return new VaultfireAgentSDK(config);
}
