/**
 * Utilization Service
 *
 * API operations for utilization calculations.
 */

import { api } from './api';

export interface OverallUtilization {
  capacity: number;
  allocated: number;
  utilization: number;
  indicator: UtilizationIndicator;
}

export interface RunningUtilization {
  capacity_ytd: number;
  allocated_ytd: number;
  utilization: number;
  indicator: UtilizationIndicator;
  months_included: number;
}

export interface UtilizationData {
  overall: OverallUtilization;
  running: RunningUtilization;
}

export interface TeamUtilization {
  average_utilization: number;
  average_indicator: UtilizationIndicator;
  member_count: number;
  by_member: Record<string, OverallUtilization>;
}

export interface TrendDataPoint {
  month: string;
  utilization: number;
  indicator: UtilizationIndicator;
  capacity: number;
  allocated: number;
}

export type UtilizationIndicator = 'gray' | 'blue' | 'green' | 'yellow' | 'red';

export interface UtilizationError {
  message: string;
  code: string;
  details?: unknown;
}

class UtilizationServiceError extends Error {
  code: string;
  details?: unknown;

  constructor(message: string, code: string, details?: unknown) {
    super(message);
    this.name = 'UtilizationServiceError';
    this.code = code;
    this.details = details;
  }
}

async function safeApiCall<T>(apiCall: () => Promise<T>): Promise<T> {
  try {
    return await apiCall();
  } catch (error) {
    const message = error instanceof Error ? error.message : 'Unknown error occurred';
    const code = 'UTILIZATION_API_ERROR';
    throw new UtilizationServiceError(message, code, error);
  }
}

// Utilization API methods
export const utilizationService = {
  /**
   * Get running (YTD) utilization for a team member
   */
  getRunning: async (teamMemberId: string, month: string): Promise<RunningUtilization> =>
    safeApiCall(() =>
      api.get<RunningUtilization>(
        `/utilization/running?team_member_id=${teamMemberId}&month=${month}`
      )
    ),

  /**
   * Get overall (monthly) utilization for a team member
   */
  getOverall: async (teamMemberId: string, month: string): Promise<OverallUtilization> =>
    safeApiCall(() =>
      api.get<OverallUtilization>(
        `/utilization/overall?team_member_id=${teamMemberId}&month=${month}`
      )
    ),

  /**
   * Get combined utilization data for a team member
   */
  getData: async (teamMemberId: string, month: string): Promise<UtilizationData> =>
    safeApiCall(() =>
      api.get<UtilizationData>(
        `/utilization/data?team_member_id=${teamMemberId}&month=${month}`
      )
    ),

  /**
   * Get team-level utilization
   */
  getTeam: async (month: string): Promise<TeamUtilization> =>
    safeApiCall(() => api.get<TeamUtilization>(`/utilization/team?month=${month}`)),

  /**
   * Get team-level running utilization YTD
   */
  getTeamRunning: async (month: string): Promise<TeamUtilization> =>
    safeApiCall(() => api.get<TeamUtilization>(`/utilization/team-running?month=${month}`)),

  /**
   * Get utilization trend over multiple months
   */
  getTrend: async (
    teamMemberId: string,
    startMonth: string,
    endMonth: string
  ): Promise<TrendDataPoint[]> =>
    safeApiCall(() =>
      api.get<TrendDataPoint[]>(
        `/utilization/trend?team_member_id=${teamMemberId}&start_month=${startMonth}&end_month=${endMonth}`
      )
    ),
};

/**
 * Get Tailwind CSS classes for utilization indicator
 */
export function getUtilizationClasses(indicator: UtilizationIndicator): {
  bg: string;
  text: string;
  border: string;
} {
  const colorMap: Record<UtilizationIndicator, { bg: string; text: string; border: string }> = {
    gray: {
      bg: 'bg-gray-100',
      text: 'text-gray-700',
      border: 'border-gray-300',
    },
    blue: {
      bg: 'bg-blue-100',
      text: 'text-blue-700',
      border: 'border-blue-300',
    },
    green: {
      bg: 'bg-green-100',
      text: 'text-green-700',
      border: 'border-green-300',
    },
    yellow: {
      bg: 'bg-yellow-100',
      text: 'text-yellow-700',
      border: 'border-yellow-300',
    },
    red: {
      bg: 'bg-red-100',
      text: 'text-red-700',
      border: 'border-red-300',
    },
  };

  return colorMap[indicator] || colorMap.gray;
}

/**
 * Get DaisyUI badge class for utilization indicator
 */
export function getUtilizationBadgeClass(indicator: UtilizationIndicator): string {
  const badgeMap: Record<UtilizationIndicator, string> = {
    gray: 'badge-neutral',
    blue: 'badge-info',
    green: 'badge-success',
    yellow: 'badge-warning',
    red: 'badge-error',
  };

  return badgeMap[indicator] || 'badge-neutral';
}

/**
 * Format utilization percentage for display
 */
export function formatUtilization(utilization: number): string {
  return `${utilization.toFixed(1)}%`;
}

/**
 * Get utilization status description
 */
export function getUtilizationStatus(indicator: UtilizationIndicator): string {
  const statusMap: Record<UtilizationIndicator, string> = {
    gray: 'Under-utilized',
    blue: 'Low utilization',
    green: 'Optimal',
    yellow: 'High utilization',
    red: 'Over-allocated',
  };

  return statusMap[indicator] || 'Unknown';
}

export default utilizationService;
