import type { Leaderboard, PredictedScore } from "../types/leaderboard";
import type { Lesson, LessonsResponse } from "../types/lesson";
import type {
  ClaimedRewardResponse,
  QuestArc,
  UserInventory,
  UserTitle,
} from "../types/quest";
import type {
  SessionAnswerResponse,
  SessionQuestionsResponse,
  SessionRequest,
  SessionResponse,
  SubmitAnswer,
} from "../types/session";
import type { PracticeSheet } from "../types/sheet";
import type { Topic } from "../types/topic";

const API_URL = "https://ed-dev-api.omukk.dev";

export interface LoginRequest {
  email: string;
  password: string;
}

export interface User {
  email: string;
  name: string;
  role: "STUDENT" | "TEACHER" | "ADMIN";
  avatar_url: string;
  id: string;
  status: "ACTIVE" | "INACTIVE";
  joined_at: string;
  last_active: string;
  total_xp: number;
  current_level: number;
  next_level_threshold: number;
  current_level_start: number;
}

export interface LoginResponse {
  token: string;
  token_type: string;
  user: User;
}

export interface ApiError {
  detail?: string;
  message?: string;
}

class ApiClient {
  private baseURL: string;

  constructor(baseURL: string) {
    this.baseURL = baseURL;
  }

  private async request<T>(
    endpoint: string,
    options: RequestInit = {},
  ): Promise<T> {
    const url = `${this.baseURL}${endpoint}`;

    const config: RequestInit = {
      ...options,
      headers: {
        "Content-Type": "application/json",
        ...options.headers,
      },
    };

    try {
      const response = await fetch(url, config);

      if (!response.ok) {
        const error: ApiError = await response.json().catch(() => ({
          message: "An error occurred",
        }));
        throw new Error(error.detail || error.message || "Request failed");
      }

      return await response.json();
    } catch (error) {
      if (error instanceof Error) {
        throw error;
      }
      throw new Error("Network error occurred");
    }
  }

  // Auth endpoints
  async login(credentials: LoginRequest): Promise<LoginResponse> {
    return this.request<LoginResponse>("/auth/login/", {
      method: "POST",
      body: JSON.stringify(credentials),
    });
  }

  // Authenticated request helper
  async authenticatedRequest<T>(
    endpoint: string,
    token: string,
    options: RequestInit = {},
  ): Promise<T> {
    return this.request<T>(endpoint, {
      ...options,
      headers: {
        ...options.headers,
        Authorization: `Bearer ${token}`,
      },
    });
  }

  // Example: Get user profile (authenticated endpoint)
  async getUserProfile(token: string): Promise<User> {
    return this.authenticatedRequest<User>("/auth/me/", token);
  }

  async getPracticeSheets(
    token: string,
    page: number,
    limit: number,
  ): Promise<any> {
    const queryParams = new URLSearchParams({
      page: page.toString(),
      limit: limit.toString(),
    }).toString();
    return this.authenticatedRequest<any>(
      `/practice-sheets/?${queryParams}`,
      token,
    );
  }

  async getPracticeSheetById(
    token: string,
    sheetId: string,
  ): Promise<PracticeSheet> {
    return this.authenticatedRequest<PracticeSheet>(
      `/practice-sheets/${sheetId}`,
      token,
    );
  }

  // async startPracticeSession(
  //   token: string,
  //   sessionData: PracticeSessionRequest,
  // ): Promise<SessionResponse> {
  //   return this.authenticatedRequest<SessionResponse>(`/sessions/`, token, {
  //     method: "POST",
  //     body: JSON.stringify(sessionData),
  //   });
  // }
  // async startTargetedPracticeSession(
  //   token: string,
  //   sessionData: TargetedSessionRequest,
  // ): Promise<TargetedSessionResponse> {
  //   return this.authenticatedRequest<TargetedSessionResponse>(
  //     `/sessions/`,
  //     token,
  //     {
  //       method: "POST",
  //       body: JSON.stringify(sessionData),
  //     },
  //   );
  // }

  async startSession(
    token: string,
    sessionData: SessionRequest,
  ): Promise<SessionResponse> {
    return this.authenticatedRequest<SessionResponse>(`/sessions/`, token, {
      method: "POST",
      body: JSON.stringify(sessionData),
    });
  }

  async fetchSessionQuestions(
    token: string,
    sessionId: string,
  ): Promise<SessionQuestionsResponse> {
    return this.authenticatedRequest<SessionQuestionsResponse>(
      `/sessions/${sessionId}/questions/`,
      token,
    );
  }

  async submitAnswer(
    token: string,
    sessionId: string,
    answerSubmissionData: SubmitAnswer,
  ): Promise<SessionAnswerResponse> {
    return this.authenticatedRequest<SessionAnswerResponse>(
      `/sessions/${sessionId}/answer/`,
      token,
      {
        method: "POST",
        body: JSON.stringify(answerSubmissionData),
      },
    );
  }

  async fetchNextModule(token: string, sessionId: string): Promise<any> {
    return this.authenticatedRequest<any>(
      `/sessions/${sessionId}/next-module/`,
      token,
      {
        method: "POST",
      },
    );
  }

  async fetchSessionStateById(
    token: string,
    sessionId: string,
  ): Promise<SessionResponse> {
    return this.authenticatedRequest<SessionResponse>(
      `/sessions/${sessionId}`,
      token,
    );
  }
  async fetchLessonVideos(token: string): Promise<LessonsResponse> {
    return this.authenticatedRequest<LessonsResponse>(`/lessons/`, token);
  }

  async fetchLessonById(token: string, lessonId: string): Promise<Lesson> {
    return this.authenticatedRequest<Lesson>(`/lessons/${lessonId}`, token);
  }
  async fetchAllTopics(token: string): Promise<Topic[]> {
    return this.authenticatedRequest<Topic[]>(`/topics/`, token);
  }

  async fetchTopicById(token: string, topicId: string): Promise<Topic> {
    return this.authenticatedRequest<Topic>(`/topics/${topicId}`, token);
  }

  async fetchLeaderboard(
    token: string,
    metric: string,
    timeframe: string,
  ): Promise<Leaderboard> {
    return this.authenticatedRequest<Leaderboard>(
      `/leaderboard/?metric=${metric}&timeframe=${timeframe}`,
      token,
    );
  }

  async fetchPredictedScore(token: string): Promise<PredictedScore> {
    return this.authenticatedRequest<PredictedScore>(`/prediction/`, token);
  }

  /*------------QUEST JOURNEY-------------- */
  async fetchUserJourney(token: string): Promise<QuestArc[]> {
    return this.authenticatedRequest<QuestArc[]>(`/journey/`, token);
  }
  async claimReward(
    token: string,
    node_id: string,
  ): Promise<ClaimedRewardResponse> {
    return this.authenticatedRequest<ClaimedRewardResponse>(
      `/journey/claim/${node_id}`,
      token,
      {
        method: "POST",
      },
    );
  }

  /*------------INVENTORY-------------- */
  async fetchUserInventory(token: string): Promise<UserInventory> {
    return this.authenticatedRequest<UserInventory>(`/inventory/`, token);
  }
  async activateItem(token: string, itemId: string): Promise<UserInventory> {
    return this.authenticatedRequest<UserInventory>(
      `/inventory/use/${itemId}`,
      token,
    );
  }
  /*------------TITLES-------------- */
  async fetchUserTitles(token: string): Promise<UserTitle[]> {
    return this.authenticatedRequest<UserTitle[]>(`/inventory/titles/`, token);
  }
  async equipTitle(
    token: string,
    titleData: { title_id: string },
  ): Promise<string> {
    return this.authenticatedRequest<string>(`/inventory/titles/equip`, token, {
      method: "POST",
      body: JSON.stringify(titleData),
    });
  }
}
export const api = new ApiClient(API_URL);
