import { readFileSync, existsSync, readdirSync } from 'fs';
import { resolve, join } from 'path';

export type TerminalConnectionProfile = {
  connectionId: string;
  version: string;
  cisDate?: string;
  client: {
    companyName: string;
    companyRegistrationNo?: string;
    address?: string;
    jurisdiction?: string;
    representedBy?: Record<string, string>;
  };
  bank?: {
    name?: string;
    accountName?: string;
    accountNumber?: string;
    iban?: string;
    swiftBic?: string;
  };
  receiver?: {
    serverId?: string;
    serverLabel?: string;
    receiverIp?: string;
    apiDocsUrl?: string;
    apiBaseUrlEnv?: string;
    apiAuthKeyEnv?: string;
  };
  alchemy?: {
    network?: string;
    apiKeyEnv?: string;
    fallbackApiKeyEnv?: string;
  };
  wallet?: {
    chain?: string;
    address?: string;
    purpose?: string;
  };
  settlementDefaults?: {
    settlementRef?: string;
    beneficiary?: string;
    beneficiaryExternalId?: string;
    currency?: string;
  };
};

function connectionsRoot(): string {
  const root =
    process.env.PROXMOX_ROOT?.trim() ||
    process.env.PHOENIX_REPO_ROOT?.trim() ||
    resolve(__dirname, '../../../../..');
  return (
    process.env.OMNL_TERMINAL_CONNECTIONS_DIR?.trim() ||
    resolve(root, 'config/omnl-terminal-connections')
  );
}

export function listTerminalConnectionIds(): string[] {
  const dir = connectionsRoot();
  if (!existsSync(dir)) return [];
  return readdirSync(dir, { withFileTypes: true })
    .filter((d) => d.isDirectory())
    .map((d) => d.name)
    .filter((id) => existsSync(join(dir, id, 'connection.v1.json')))
    .sort();
}

export function loadTerminalConnection(connectionId: string): TerminalConnectionProfile {
  const id = connectionId.trim();
  if (!id || /[^a-z0-9-]/i.test(id)) {
    throw new Error('Invalid connectionId');
  }
  const p = join(connectionsRoot(), id, 'connection.v1.json');
  if (!existsSync(p)) {
    throw new Error(`Connection profile not found: ${id}`);
  }
  const profile = JSON.parse(readFileSync(p, 'utf8')) as TerminalConnectionProfile;
  if (profile.connectionId !== id) {
    throw new Error(`connectionId mismatch: folder ${id} vs JSON ${profile.connectionId}`);
  }
  return profile;
}

export function connectionProjectDir(connectionId: string): string {
  return join(connectionsRoot(), connectionId.trim());
}

export function resolveConnectionSecret(profile: TerminalConnectionProfile, primaryEnv: string, fallbackEnv?: string): string {
  const primary = process.env[primaryEnv]?.trim();
  if (primary) return primary;
  if (fallbackEnv) {
    const fb = process.env[fallbackEnv]?.trim();
    if (fb) return fb;
  }
  return '';
}

export function connectionAlchemyApiKey(profile: TerminalConnectionProfile): string {
  const primary = profile.alchemy?.apiKeyEnv || 'MK_ALBERT_GATE_ALCHEMY_API_KEY';
  const fallback = profile.alchemy?.fallbackApiKeyEnv || 'ALCHEMY_API_KEY';
  return resolveConnectionSecret(profile, primary, fallback);
}

export function connectionReceiverConfig(profile: TerminalConnectionProfile): {
  baseUrl: string;
  authKey: string;
  configured: boolean;
} {
  const baseEnv = profile.receiver?.apiBaseUrlEnv || 'MK_ALBERT_GATE_RECEIVER_API_BASE_URL';
  const authEnv = profile.receiver?.apiAuthKeyEnv || 'MK_ALBERT_GATE_RECEIVER_API_AUTH_KEY';
  const baseUrl = process.env[baseEnv]?.trim() || '';
  const authKey = process.env[authEnv]?.trim() || '';
  return { baseUrl, authKey, configured: Boolean(baseUrl && authKey) };
}

export function buildConnectionPublicSummary(profile: TerminalConnectionProfile): Record<string, unknown> {
  const alchemyKey = connectionAlchemyApiKey(profile);
  const receiver = connectionReceiverConfig(profile);
  return {
    connectionId: profile.connectionId,
    version: profile.version,
    cisDate: profile.cisDate,
    client: profile.client,
    bank: profile.bank
      ? {
          ...profile.bank,
          accountNumber: profile.bank.accountNumber
            ? `****${String(profile.bank.accountNumber).slice(-4)}`
            : undefined,
          iban: profile.bank.iban ? `****${String(profile.bank.iban).slice(-4)}` : undefined,
        }
      : undefined,
    receiver: {
      serverId: profile.receiver?.serverId,
      serverLabel: profile.receiver?.serverLabel,
      receiverIp: profile.receiver?.receiverIp,
      apiDocsUrl: profile.receiver?.apiDocsUrl,
      configured: receiver.configured,
    },
    wallet: profile.wallet,
    settlementDefaults: profile.settlementDefaults,
    secrets: {
      alchemyConfigured: Boolean(alchemyKey),
      receiverApiConfigured: receiver.configured,
    },
    projectDir: connectionProjectDir(profile.connectionId),
  };
}
