import client from './client'
import type { Marathon, MarathonListItem, MarathonPublicInfo, MarathonUpdate, LeaderboardEntry, ParticipantWithUser, ParticipantRole, GameProposalMode, MarathonDispute, ExiledGame } from '@/types'

export interface CreateMarathonData {
  title: string
  description?: string
  start_date: string
  duration_days?: number
  is_public?: boolean
  game_proposal_mode?: GameProposalMode
}

export type { MarathonUpdate }

export const marathonsApi = {
  list: async (): Promise<MarathonListItem[]> => {
    const response = await client.get<MarathonListItem[]>('/marathons')
    return response.data
  },

  get: async (id: number): Promise<Marathon> => {
    const response = await client.get<Marathon>(`/marathons/${id}`)
    return response.data
  },

  getByCode: async (inviteCode: string): Promise<MarathonPublicInfo> => {
    // Public endpoint - no auth required
    const response = await client.get<MarathonPublicInfo>(`/marathons/by-code/${inviteCode}`)
    return response.data
  },

  create: async (data: CreateMarathonData): Promise<Marathon> => {
    const response = await client.post<Marathon>('/marathons', data)
    return response.data
  },

  update: async (id: number, data: MarathonUpdate): Promise<Marathon> => {
    const response = await client.patch<Marathon>(`/marathons/${id}`, data)
    return response.data
  },

  delete: async (id: number): Promise<void> => {
    await client.delete(`/marathons/${id}`)
  },

  start: async (id: number): Promise<Marathon> => {
    const response = await client.post<Marathon>(`/marathons/${id}/start`)
    return response.data
  },

  finish: async (id: number): Promise<Marathon> => {
    const response = await client.post<Marathon>(`/marathons/${id}/finish`)
    return response.data
  },

  join: async (inviteCode: string): Promise<Marathon> => {
    const response = await client.post<Marathon>('/marathons/join', { invite_code: inviteCode })
    return response.data
  },

  joinPublic: async (id: number): Promise<Marathon> => {
    const response = await client.post<Marathon>(`/marathons/${id}/join`)
    return response.data
  },

  getParticipants: async (id: number): Promise<ParticipantWithUser[]> => {
    const response = await client.get<ParticipantWithUser[]>(`/marathons/${id}/participants`)
    return response.data
  },

  setParticipantRole: async (marathonId: number, userId: number, role: ParticipantRole): Promise<ParticipantWithUser> => {
    const response = await client.patch<ParticipantWithUser>(
      `/marathons/${marathonId}/participants/${userId}/role`,
      { role }
    )
    return response.data
  },

  getLeaderboard: async (id: number): Promise<LeaderboardEntry[]> => {
    const response = await client.get<LeaderboardEntry[]>(`/marathons/${id}/leaderboard`)
    return response.data
  },

  uploadCover: async (id: number, file: File): Promise<Marathon> => {
    const formData = new FormData()
    formData.append('file', file)
    const response = await client.post<Marathon>(`/marathons/${id}/cover`, formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    })
    return response.data
  },

  deleteCover: async (id: number): Promise<Marathon> => {
    const response = await client.delete<Marathon>(`/marathons/${id}/cover`)
    return response.data
  },

  // Disputes management for organizers
  listDisputes: async (id: number, status: 'open' | 'all' = 'open'): Promise<MarathonDispute[]> => {
    const response = await client.get<MarathonDispute[]>(`/marathons/${id}/disputes`, {
      params: { status_filter: status }
    })
    return response.data
  },

  resolveDispute: async (marathonId: number, disputeId: number, isValid: boolean): Promise<{ message: string }> => {
    const response = await client.post<{ message: string }>(
      `/marathons/${marathonId}/disputes/${disputeId}/resolve`,
      { is_valid: isValid }
    )
    return response.data
  },

  // === Moderation ===

  // Skip participant's assignment (organizer only)
  skipParticipantAssignment: async (
    marathonId: number,
    userId: number,
    exile: boolean = false,
    reason?: string
  ): Promise<{ message: string }> => {
    const response = await client.post<{ message: string }>(
      `/marathons/${marathonId}/participants/${userId}/skip-assignment`,
      { exile, reason }
    )
    return response.data
  },

  // Get participant's exiled games (organizer only)
  getExiledGames: async (marathonId: number, userId: number): Promise<ExiledGame[]> => {
    const response = await client.get<ExiledGame[]>(
      `/marathons/${marathonId}/participants/${userId}/exiled-games`
    )
    return response.data
  },

  // Restore exiled game (organizer only)
  restoreExiledGame: async (marathonId: number, userId: number, gameId: number): Promise<{ message: string }> => {
    const response = await client.post<{ message: string }>(
      `/marathons/${marathonId}/participants/${userId}/exiled-games/${gameId}/restore`
    )
    return response.data
  },
}
