import type {
  BillingStats,
  BillingOptions,
  BillingSettings,
  BillingClientRow,
  BillingClientDetail,
  BillingActionResult,
  UpdateBillingConfigPayload,
  UpdateBillingSettingsPayload,
  DirectDebitMandateState,
  BillingProduct,
  BillingProductPayload,
  BillingProfile,
  BillingProfilePayload,
  PennylaneCustomer,
  PennylaneLinkState,
  VehiclePlansState,
  UpdateVehiclePlansPayload,
  PlanPricePayload,
} from "@/domain/entities/billing";
import type { BillingRepository } from "@/domain/repositories/billing.repository";
import type { BackendPaginatedData, PaginationQueryParams } from "@/shared/types";
import { api } from "@/infrastructure/api/api-client";

const BASE = "/billing";

export class BillingRepositoryImpl implements BillingRepository {
  getStats() {
    return api.get<BillingStats>(`${BASE}/stats`);
  }

  getOptions() {
    return api.get<BillingOptions>(`${BASE}/options`);
  }

  getSettings() {
    return api.get<BillingSettings>(`${BASE}/settings`);
  }

  updateSettings(payload: UpdateBillingSettingsPayload) {
    return api.put<BillingSettings>(`${BASE}/settings`, payload);
  }

  getProducts() {
    return api.get<BillingProduct[]>(`${BASE}/products`);
  }

  createProduct(payload: BillingProductPayload) {
    return api.post<BillingProduct[]>(`${BASE}/products`, payload);
  }

  updateProduct(productId: number, payload: BillingProductPayload) {
    return api.put<BillingProduct[]>(`${BASE}/products/${productId}`, payload);
  }

  findClients(params: PaginationQueryParams) {
    return api.get<BackendPaginatedData<BillingClientRow>>(`${BASE}/clients`, { params });
  }

  findClient(clientId: number) {
    return api.get<BillingClientDetail>(`${BASE}/clients/${clientId}`);
  }

  updateClientConfig(clientId: number, payload: UpdateBillingConfigPayload) {
    return api.put<BillingClientDetail>(`${BASE}/clients/${clientId}`, payload);
  }

  suspendClient(clientId: number) {
    return api.post<BillingActionResult>(`${BASE}/clients/${clientId}/suspend`);
  }

  reactivateClient(clientId: number) {
    return api.post<BillingActionResult>(`${BASE}/clients/${clientId}/reactivate`);
  }

  markInvoicePaid(invoiceId: number) {
    return api.post<BillingActionResult>(`${BASE}/invoices/${invoiceId}/mark-paid`);
  }

  getMandate(clientId: number) {
    return api.get<DirectDebitMandateState>(`${BASE}/clients/${clientId}/mandate`);
  }

  requestMandate(clientId: number) {
    return api.post<DirectDebitMandateState>(`${BASE}/clients/${clientId}/mandate`);
  }

  getProfile(clientId: number) {
    return api.get<BillingProfilePayload>(`${BASE}/clients/${clientId}/profile`);
  }

  updateProfile(clientId: number, profile: Omit<BillingProfile, "updated_at">) {
    return api.put<BillingProfilePayload>(`${BASE}/clients/${clientId}/profile`, profile);
  }

  getPennylaneLink(clientId: number) {
    return api.get<PennylaneLinkState>(`${BASE}/clients/${clientId}/pennylane`);
  }

  searchPennylaneCustomers(query: string) {
    return api.get<PennylaneCustomer[]>(`${BASE}/pennylane/customers`, { params: { q: query } });
  }

  updatePennylaneLink(clientId: number, customerId: number | null) {
    return api.put<PennylaneLinkState>(`${BASE}/clients/${clientId}/pennylane`, { customer_id: customerId });
  }

  getVehiclePlans(clientId: number) {
    return api.get<VehiclePlansState>(`${BASE}/clients/${clientId}/vehicle-plans`);
  }

  updateVehiclePlans(clientId: number, payload: UpdateVehiclePlansPayload) {
    return api.post<VehiclePlansState>(`${BASE}/clients/${clientId}/vehicle-plans`, payload);
  }

  updatePlanPrices(clientId: number, prices: PlanPricePayload[]) {
    return api.put<VehiclePlansState>(`${BASE}/clients/${clientId}/plan-prices`, { prices });
  }
}
