import { buildDossierFolderPlan } from "./drive";
import { buildCreationUpdate, buildMondayCreateVariables } from "./monday";
import { buildDriveFolderName, type CreateDossierInput } from "./contracts";

export type IntegrationPorts = {
  drive: {
    createDossierTree(input: CreateDossierInput): Promise<{ folderId: string; folderUrl: string }>;
  };
  portal: {
    createAccess(input: CreateDossierInput): Promise<{ token: string; url: string }>;
  };
  monday: {
    createItem(variables: ReturnType<typeof buildMondayCreateVariables>): Promise<{ itemId: string; itemUrl: string }>;
    createUpdate(itemId: string, body: string): Promise<void>;
  };
  config: {
    mondayBoardId: string;
    mondayInProgressGroupId: string;
    driveInProgressFolderId: string;
  };
};

export async function createDossier(input: CreateDossierInput, ports: IntegrationPorts) {
  // Compensation is intentionally explicit: if Monday fails after Drive succeeds,
  // the Drive folder is preserved and the incident is reported for manual recovery.
  const drivePlan = buildDossierFolderPlan(input, ports.config.driveInProgressFolderId);
  const drive = await ports.drive.createDossierTree(input);
  const portal = await ports.portal.createAccess(input);
  const mondayVariables = buildMondayCreateVariables(
    input,
    ports.config.mondayInProgressGroupId,
    ports.config.mondayBoardId,
    { driveUrl: drive.folderUrl, portalUrl: portal.url },
  );
  const monday = await ports.monday.createItem(mondayVariables);
  await ports.monday.createUpdate(monday.itemId, buildCreationUpdate(input, buildDriveFolderName(input)));

  return {
    reference: input.reference,
    mondayItemId: monday.itemId,
    mondayItemUrl: monday.itemUrl,
    driveFolderId: drive.folderId,
    driveFolderUrl: drive.folderUrl,
    portalToken: portal.token,
    portalUrl: portal.url,
    folderPlan: drivePlan,
  };
}
