/**
 * @module cw.opportunityService
 *
 * ConnectWise Opportunity Service
 * ================================
 *
 * Methods for ConnectWise integrations that the opportunity workflow
 * calls. Some are still stubs (marked with console.warn); others are
 * fully implemented against the CW REST API.
 */

import { opportunityCw } from "../modules/cw-utils/opportunities/opportunities";
import { connectWiseApi } from "../constants";

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

export interface TimeEntryInput {
  /** CW activity ID to charge the time entry to. */
  activityId: number;
  /** CW member ID of the user submitting time. */
  cwMemberId: number;
  /** ISO-8601 datetime when work started. */
  timeStart: string;
  /** ISO-8601 datetime when work ended. */
  timeEnd: string;
  notes: string;
}

export interface TimeEntryResult {
  success: boolean;
  cwTimeEntryId: number | null;
  message: string;
}

export interface StatusSyncInput {
  opportunityId: number;
  statusCwId: number;
}

export interface StatusSyncResult {
  success: boolean;
  message: string;
}

// ---------------------------------------------------------------------------
// Service
// ---------------------------------------------------------------------------

/**
 * Submit a time entry to ConnectWise for an opportunity activity.
 *
 * Called automatically whenever `timeStart` and `timeEnd` are provided
 * on a workflow action.
 */
export async function submitTimeEntry(
  input: TimeEntryInput,
): Promise<TimeEntryResult> {
  try {
    const stripMs = (d: string) => d.replace(/\.\d{3}Z$/, "Z");

    const response = await connectWiseApi.post("/time/entries", {
      member: { id: input.cwMemberId },
      chargeToType: "Activity",
      chargeToId: input.activityId,
      timeStart: stripMs(input.timeStart),
      timeEnd: stripMs(input.timeEnd),
      notes: input.notes,
    });

    return {
      success: true,
      cwTimeEntryId: response.data?.id ?? null,
      message: `Time entry ${response.data?.id} created for activity ${input.activityId}.`,
    };
  } catch (error: any) {
    console.error(
      `[cw.opportunityService] submitTimeEntry FAILED — activityId=${input.activityId}, cwMemberId=${input.cwMemberId}`,
      error?.response?.data ?? error,
    );
    return {
      success: false,
      cwTimeEntryId: null,
      message: `Failed to submit time entry: ${error?.message ?? "Unknown error"}`,
    };
  }
}

/**
 * Sync an opportunity's status to ConnectWise.
 *
 * Called whenever the workflow transitions an opportunity to a new
 * status, ensuring the CW record stays in sync.
 */
export async function syncOpportunityStatus(
  input: StatusSyncInput,
): Promise<StatusSyncResult> {
  try {
    await opportunityCw.update(input.opportunityId, {
      status: { id: input.statusCwId },
    });

    return {
      success: true,
      message: `Opportunity ${input.opportunityId} status synced to CW status ID ${input.statusCwId}.`,
    };
  } catch (error: any) {
    console.error(
      `[cw.opportunityService] syncOpportunityStatus FAILED — opportunityId=${input.opportunityId}, statusCwId=${input.statusCwId}`,
      error?.response?.data ?? error,
    );
    return {
      success: false,
      message: `Failed to sync opportunity status: ${error?.message ?? "Unknown error"}`,
    };
  }
}
