import { ActivityController } from "../controllers/ActivityController";
import GenericError from "../Errors/GenericError";
import { activityCw } from "../modules/cw-utils/activities/activities";
import {
  CWCreateActivity,
  CWPatchOperation,
} from "../modules/cw-utils/activities/activity.types";

export const activities = {
  /**
   * Fetch Activity
   *
   * Fetch a single activity by its ConnectWise activity ID
   * and return an ActivityController instance.
   *
   * @param cwActivityId - The ConnectWise activity ID
   * @returns {Promise<ActivityController>}
   */
  async fetchItem(cwActivityId: number): Promise<ActivityController> {
    // TODO: Query local Activity table when synced by dalpuri
    throw new GenericError({
      name: "NotAvailable",
      message: "Activity fetch from local DB not yet implemented",
      status: 501,
    });
  },

  /**
   * Fetch All Activities (Paginated)
   *
   * @param page - Page number (1-based)
   * @param rpp  - Records per page
   * @param conditions - Optional conditions string for filtering
   * @returns {Promise<ActivityController[]>}
   */
  async fetchPages(
    page: number,
    rpp: number,
    conditions?: string,
  ): Promise<ActivityController[]> {
    // TODO: Query local Activity table when synced by dalpuri
    return [];
  },

  /**
   * Fetch Activities by Company
   *
   * @param cwCompanyId - The ConnectWise company ID
   * @returns {Promise<ActivityController[]>}
   */
  async fetchByCompany(cwCompanyId: number): Promise<ActivityController[]> {
    // TODO: Query local Activity table when synced by dalpuri
    return [];
  },

  /**
   * Fetch Activities by Opportunity
   *
   * @param cwOpportunityId - The ConnectWise opportunity ID
   * @returns {Promise<ActivityController[]>}
   */
  async fetchByOpportunity(
    cwOpportunityId: number,
  ): Promise<ActivityController[]> {
    // TODO: Query local Activity table when synced by dalpuri
    return [];
  },

  /**
   * Create Activity
   *
   * Creates a new activity in ConnectWise and returns an ActivityController.
   *
   * @param data - The activity data to create
   * @returns {Promise<ActivityController>}
   */
  async create(data: CWCreateActivity): Promise<ActivityController> {
    try {
      return await ActivityController.create(data);
    } catch (error) {
      const errBody = (error as any).response?.data || error;
      throw new GenericError({
        name: "CreateActivityError",
        message: "Failed to create activity in ConnectWise",
        cause: typeof errBody === "string" ? errBody : JSON.stringify(errBody),
        status: 502,
      });
    }
  },

  /**
   * Update Activity
   *
   * Updates an existing activity in ConnectWise using JSON Patch operations
   * and returns an updated ActivityController.
   *
   * @param cwActivityId - The ConnectWise activity ID to update
   * @param operations - Array of JSON Patch operations to apply
   * @returns {Promise<ActivityController>}
   */
  async update(
    cwActivityId: number,
    operations: CWPatchOperation[],
  ): Promise<ActivityController> {
    try {
      const updated = await activityCw.update(cwActivityId, operations);
      return new ActivityController(updated);
    } catch (error) {
      const errBody = (error as any).response?.data || error;
      throw new GenericError({
        name: "UpdateActivityError",
        message: `Failed to update activity ${cwActivityId}`,
        cause: typeof errBody === "string" ? errBody : JSON.stringify(errBody),
        status: 502,
      });
    }
  },

  /**
   * Delete Activity
   *
   * Deletes an activity from ConnectWise.
   *
   * @param cwActivityId - The ConnectWise activity ID to delete
   */
  async delete(cwActivityId: number): Promise<void> {
    try {
      await activityCw.delete(cwActivityId);
    } catch (error) {
      const errBody = (error as any).response?.data || error;
      throw new GenericError({
        name: "DeleteActivityError",
        message: `Failed to delete activity ${cwActivityId}`,
        cause: typeof errBody === "string" ? errBody : JSON.stringify(errBody),
        status: 502,
      });
    }
  },

  /**
   * Count Activities
   *
   * Returns the total number of activities, optionally filtered.
   *
   * @param conditions - Optional CW conditions string for filtering
   * @returns {Promise<number>}
   */
  async count(conditions?: string): Promise<number> {
    // TODO: Count from local Activity table when synced by dalpuri
    return 0;
  },
};
