import * as crypto from 'crypto';

const PAYSTACK_BASE = 'https://api.paystack.co';

export class PaystackError extends Error {
  statusCode: number;

  constructor(message: string, statusCode = 400) {
    super(message);
    this.name = 'PaystackError';
    this.statusCode = statusCode;
  }
}

export function getPaystackSecret() {
  const secret = process.env.PAYSTACK_SECRET?.trim();
  if (!secret) {
    throw new PaystackError('PAYSTACK_SECRET is not configured', 500);
  }
  return secret;
}

export function ghsToPesewas(amountGhs: number) {
  return Math.round(Number(amountGhs || 0) * 100);
}

export function pesewasToGhs(amountPesewas: number) {
  return Number(amountPesewas || 0) / 100;
}

async function paystackRequest<T>(method: string, path: string, body?: Record<string, unknown>): Promise<T> {
  const secret = getPaystackSecret();
  const response = await fetch(`${PAYSTACK_BASE}${path}`, {
    method,
    headers: {
      Authorization: `Bearer ${secret}`,
      'Content-Type': 'application/json',
    },
    body: body ? JSON.stringify(body) : undefined,
  });

  const payload = (await response.json().catch(() => ({}))) as {
    status?: boolean;
    message?: string;
    data?: T;
  };

  if (!response.ok || payload?.status === false) {
    throw new PaystackError(payload?.message || 'Paystack request failed', response.status);
  }

  return payload.data as T;
}

export async function createPaymentPage(input: {
  name: string;
  amountGhs: number;
  description?: string;
}) {
  const data = await paystackRequest<{
    id: number;
    slug: string;
    url?: string;
  }>('POST', '/page', {
    name: input.name,
    amount: ghsToPesewas(input.amountGhs),
    description: input.description || input.name,
    currency: 'GHS',
  });

  return {
    id: data.id,
    slug: data.slug,
    url: data.url || `https://paystack.com/pay/${data.slug}`,
  };
}

export async function initializeTransaction(input: {
  email: string;
  amountGhs: number;
  reference: string;
  callbackUrl?: string;
  metadata?: Record<string, unknown>;
}) {
  const data = await paystackRequest<{
    authorization_url: string;
    access_code: string;
    reference: string;
  }>('POST', '/transaction/initialize', {
    email: input.email,
    amount: ghsToPesewas(input.amountGhs),
    currency: 'GHS',
    reference: input.reference,
    callback_url: input.callbackUrl,
    metadata: input.metadata || {},
  });

  return data;
}

export async function verifyTransaction(reference: string) {
  return paystackRequest<{
    status: string;
    reference: string;
    amount: number;
    currency: string;
    paid_at?: string;
    customer?: { email?: string };
    metadata?: Record<string, unknown>;
  }>('GET', `/transaction/verify/${encodeURIComponent(reference)}`);
}

export function verifyWebhookSignature(rawBody: string, signature: string | undefined) {
  if (!signature) return false;
  const secret = getPaystackSecret();
  const hash = crypto.createHmac('sha512', secret).update(rawBody).digest('hex');
  return hash === signature;
}
