import { db } from "@/app/db/db";
import { pibiRequests } from "@/app/db/schema/pibi_requests";
import { eq, and } from "drizzle-orm";
import { syncMeasuresFieldToHubSpot as defaultSyncMeasuresField } from "@/app/lib/hubspot/dealSync";
export { PIBI_ORDERED_TEXT_PROP } from "./createPibiRequests";
import { PIBI_ORDERED_TEXT_PROP } from "./createPibiRequests";

// ---------------------------------------------------------------------------
// Injectable dep types
// ---------------------------------------------------------------------------

export type RunDeletePibiTx = (params: {
  id: bigint;
  dealId: string;
}) => Promise<{ remainingMeasureNames: string[] }>;

export type SyncMeasuresField = typeof defaultSyncMeasuresField;

// ---------------------------------------------------------------------------
// Result type
// ---------------------------------------------------------------------------

export type DeletePibiRequestResult =
  | { ok: true; hubspotSync: "ok" | "failed"; hubspotError?: string }
  | { ok: false; error: string };

export interface DeletePibiRequestInput {
  id: bigint;
  dealId: string;
  deps?: {
    runDeleteTx?: RunDeletePibiTx;
    syncMeasuresField?: SyncMeasuresField;
  };
}

// ---------------------------------------------------------------------------
// Default DB-backed implementation
// ---------------------------------------------------------------------------

const defaultRunDeleteTx: RunDeletePibiTx = async ({ id, dealId }) => {
  return await db.transaction(async (tx) => {
    const deleted = await tx
      .delete(pibiRequests)
      .where(and(eq(pibiRequests.id, id), eq(pibiRequests.hubspotDealId, dealId)))
      .returning({ id: pibiRequests.id });

    if (deleted.length === 0) {
      throw new Error("PIBI request not found");
    }

    const remaining = await tx
      .select({ measureName: pibiRequests.measureName })
      .from(pibiRequests)
      .where(eq(pibiRequests.hubspotDealId, dealId));

    return { remainingMeasureNames: remaining.map((r) => r.measureName) };
  });
};

// ---------------------------------------------------------------------------
// Service entry-point
// ---------------------------------------------------------------------------

export async function deletePibiRequest(
  input: DeletePibiRequestInput,
): Promise<DeletePibiRequestResult> {
  const runDeleteTx = input.deps?.runDeleteTx ?? defaultRunDeleteTx;
  const syncMeasuresField = input.deps?.syncMeasuresField ?? defaultSyncMeasuresField;

  let txResult: { remainingMeasureNames: string[] };
  try {
    txResult = await runDeleteTx({ id: input.id, dealId: input.dealId });
  } catch (err) {
    const message = err instanceof Error ? err.message : "Failed to delete PIBI request";
    return { ok: false, error: message };
  }

  const syncResult = await syncMeasuresField({
    hubspotDealId: input.dealId,
    propName: PIBI_ORDERED_TEXT_PROP,
    measureNames: txResult.remainingMeasureNames,
  });

  if (syncResult.ok) {
    return { ok: true, hubspotSync: "ok" };
  }

  return {
    ok: true,
    hubspotSync: "failed",
    hubspotError: syncResult.error,
  };
}
