import { API_BASE_URL, API_ENDPOINTS } from "../config/api";
import log from "../utils/logger";

export interface FitnessGoal {
  id: string;
  userId: string;
  fitnessProfileId?: string;
  goalType:
    | "weight_target"
    | "strength_milestone"
    | "endurance_target"
    | "flexibility_goal"
    | "habit_building"
    | "custom";
  title: string;
  description?: string;
  targetValue?: number;
  currentValue?: number;
  unit?: string;
  startDate: string;
  targetDate?: string;
  completedDate?: string;
  status: "active" | "completed" | "abandoned" | "paused";
  progress: number;
  priority: "low" | "medium" | "high";
  notes?: string;
  createdAt: string;
  updatedAt: string;
}

export interface CreateGoalData {
  goalType: FitnessGoal["goalType"];
  title: string;
  description?: string;
  targetValue?: number;
  currentValue?: number;
  unit?: string;
  targetDate?: string;
  priority?: FitnessGoal["priority"];
  notes?: string;
}

export class FitnessGoalsService {
  private async getAuthHeaders(token: string | null): Promise<any> {
    const headers: any = {
      "Content-Type": "application/json",
    };

    if (token) {
      headers["Authorization"] = `Bearer ${token}`;
    }

    return headers;
  }

  async getGoals(
    userId: string,
    token: string | null,
    status?: string,
  ): Promise<FitnessGoal[]> {
    try {
      const headers = await this.getAuthHeaders(token);
      let url = `${API_BASE_URL}${API_ENDPOINTS.FITNESS_GOALS.LIST}?userId=${userId}`;

      if (status && status !== "all") {
        url += `&status=${status}`;
      }

      const response = await fetch(url, { headers });

      if (!response.ok) {
        throw new Error(`Failed to fetch goals: ${response.status}`);
      }

      const result = await response.json();

      // Handle standardized API response format
      // API returns: { success: true, data: [...], meta: {...} }
      if (result.success && result.data) {
        return Array.isArray(result.data) ? result.data : [];
      }

      // Fallback for legacy format (direct array)
      return Array.isArray(result) ? result : [];
    } catch (error) {
      log.error("Failed to fetch fitness goals", error);
      throw error;
    }
  }

  async createGoal(
    goalData: CreateGoalData,
    token: string | null,
  ): Promise<FitnessGoal> {
    try {
      const headers = await this.getAuthHeaders(token);
      const response = await fetch(
        `${API_BASE_URL}${API_ENDPOINTS.FITNESS_GOALS.CREATE}`,
        {
          method: "POST",
          headers,
          body: JSON.stringify(goalData),
        },
      );

      if (!response.ok) {
        const error = await response.json();
        throw new Error(error.error || "Failed to create goal");
      }

      const result = await response.json();

      // Handle standardized API response format
      if (result.success && result.data) {
        return result.data;
      }

      // Fallback for legacy format
      return result;
    } catch (error) {
      log.error("Failed to create fitness goal", error);
      throw error;
    }
  }

  async updateGoal(
    id: string,
    updates: Partial<FitnessGoal>,
    token: string | null,
  ): Promise<FitnessGoal> {
    try {
      const headers = await this.getAuthHeaders(token);
      const response = await fetch(
        `${API_BASE_URL}${API_ENDPOINTS.FITNESS_GOALS.UPDATE(id)}`,
        {
          method: "PUT",
          headers,
          body: JSON.stringify(updates),
        },
      );

      if (!response.ok) {
        throw new Error("Failed to update goal");
      }

      const result = await response.json();

      // Handle standardized API response format
      if (result.success && result.data) {
        return result.data;
      }

      // Fallback for legacy format
      return result;
    } catch (error) {
      log.error("Failed to update fitness goal", error);
      throw error;
    }
  }

  async updateProgress(
    id: string,
    currentValue: number,
    token: string | null,
  ): Promise<FitnessGoal> {
    return this.updateGoal(id, { currentValue }, token);
  }

  async completeGoal(id: string, token: string | null): Promise<FitnessGoal> {
    try {
      const headers = await this.getAuthHeaders(token);
      const response = await fetch(
        `${API_BASE_URL}${API_ENDPOINTS.FITNESS_GOALS.COMPLETE(id)}`,
        {
          method: "POST",
          headers,
        },
      );

      if (!response.ok) {
        throw new Error("Failed to complete goal");
      }

      const result = await response.json();

      // Note: Complete endpoint returns direct object (legacy format)
      // Handle standardized API response format (if migrated)
      if (result.success && result.data) {
        return result.data;
      }

      // Fallback for legacy format (current implementation)
      return result;
    } catch (error) {
      log.error("Failed to complete fitness goal", error);
      throw error;
    }
  }

  async deleteGoal(id: string, token: string | null): Promise<void> {
    try {
      const headers = await this.getAuthHeaders(token);
      const response = await fetch(
        `${API_BASE_URL}${API_ENDPOINTS.FITNESS_GOALS.DELETE(id)}`,
        {
          method: "DELETE",
          headers,
        },
      );

      if (!response.ok) {
        throw new Error("Failed to delete goal");
      }

      // DELETE endpoint returns: { success: true, data: { deleted: true }, meta: {...} }
      // No need to parse the result for void return type
    } catch (error) {
      log.error("Failed to delete fitness goal", error);
      throw error;
    }
  }
}

export const fitnessGoalsService = new FitnessGoalsService();
