import type { BillingType, RecurringBillingProvider } from "./types";

const formatDate = (date: Date) => date.toISOString().slice(0, 10);

export class AsaasError extends Error {
  constructor(public status: number, public details: unknown) { super(`Asaas request failed (${status})`); }
}

export class AsaasProvider implements RecurringBillingProvider {
  constructor(private apiKey = process.env.ASAAS_API_KEY, private baseUrl = process.env.ASAAS_API_URL ?? "https://api-sandbox.asaas.com/v3") {
    if (!apiKey) throw new Error("ASAAS_API_KEY não configurada");
  }

  private async request<T>(path: string, body: unknown, method="POST"): Promise<T> {
    const response = await fetch(`${this.baseUrl}${path}`, { method, headers: { "Content-Type": "application/json", "User-Agent": "ShopCompras/0.1 (Next.js)", access_token: this.apiKey! }, body: JSON.stringify(body), cache: "no-store" });
    const payload = await response.json().catch(() => null);
    if (!response.ok) throw new AsaasError(response.status, payload);
    return payload as T;
  }

  createCustomer(input: { tenantId: string; name: string; document: string; email: string; phone: string }) {
    return this.request<{ id: string }>("/customers", { name: input.name, cpfCnpj: input.document, email: input.email, mobilePhone: input.phone, externalReference: input.tenantId, notificationDisabled: false });
  }

  createSubscription(input: { localSubscriptionId: string; customerId: string; billingType: BillingType; valueCents: number; nextDueDate: Date; description: string }) {
    return this.request<{ id: string; status?: string }>("/subscriptions", { customer: input.customerId, billingType: input.billingType, value: input.valueCents / 100, nextDueDate: formatDate(input.nextDueDate), cycle: "MONTHLY", description: input.description.slice(0, 500), externalReference: input.localSubscriptionId });
  }

  updateSubscription(input:{subscriptionId:string;valueCents:number;description:string;updatePendingPayments:boolean}){
    return this.request<{id:string;status?:string}>(`/subscriptions/${input.subscriptionId}`,{value:input.valueCents/100,description:input.description.slice(0,500),updatePendingPayments:input.updatePendingPayments},"PUT");
  }

  createPayment(input:{leadId:string;customerId:string;valueCents:number;dueDate:Date;description:string}){
    return this.request<{id:string;invoiceUrl?:string;bankSlipUrl?:string}>("/payments",{customer:input.customerId,billingType:"UNDEFINED",value:input.valueCents/100,dueDate:formatDate(input.dueDate),description:input.description.slice(0,500),externalReference:input.leadId});
  }
}
