import { api, apiClient, API_ENDPOINTS } from '@/services/api'
import type {
  Chore,
  ChoreCreate,
  ChoreUpdate,
  ChoreType,
  ChoreAssignment,
  ChoreAssignmentCreate,
  ChoreAssignmentUpdate,
  ChoreHistory,
} from '@/types/chore'
import { groupService } from './groupService'
import type { Group } from '@/types/group'

export const choreService = {
  async getAllChores(): Promise<Chore[]> {
    try {
      const response = await api.get(API_ENDPOINTS.CHORES.ALL)
      return response.data
    } catch (error) {
      console.error('Failed to get all chores via optimized endpoint, falling back to individual calls:', error)
      return this.getAllChoresFallback()
    }
  },

  async getAllChoresFallback(): Promise<Chore[]> {
    let allChores: Chore[] = []
    try {
      const personalChores = await this.getPersonalChores()
      allChores = allChores.concat(personalChores)

      const userGroups: Group[] = await groupService.getUserGroups()
      for (const group of userGroups) {
        try {
          const groupChores = await this.getChores(group.id)
          allChores = allChores.concat(groupChores)
        } catch (groupError) {
          console.error(`Failed to get chores for group ${group.id} (${group.name}):`, groupError)
        }
      }
    } catch (error) {
      console.error('Failed to get all chores:', error)
      throw error
    }
    return allChores
  },

  async getChores(groupId: number): Promise<Chore[]> {
    const response = await api.get(API_ENDPOINTS.CHORES.GROUP_CHORES(groupId))
    return response.data
  },

  async createChore(chore: ChoreCreate): Promise<Chore> {
    if (chore.type === 'personal') {
      const response = await api.post(API_ENDPOINTS.CHORES.PERSONAL, chore)
      return response.data
    } else if (chore.type === 'group' && chore.group_id) {
      const response = await api.post(API_ENDPOINTS.CHORES.GROUP_CHORES(chore.group_id), chore)
      return response.data
    } else {
      throw new Error('Invalid chore type or missing group_id for group chore')
    }
  },

  async updateChore(choreId: number, chore: ChoreUpdate, originalChore?: Chore): Promise<Chore> {
    // Check if this is a type conversion (personal to group or group to personal)
    const isTypeConversion = originalChore && chore.type && originalChore.type !== chore.type;

    if (isTypeConversion) {
      // Use the new general endpoint for type conversions
      const response = await api.put(API_ENDPOINTS.CHORES.UPDATE_ANY_TYPE(choreId), chore)
      return response.data
    }

    if (chore.type === 'personal') {
      const response = await api.put(API_ENDPOINTS.CHORES.PERSONAL_BY_ID(choreId), chore)
      return response.data
    } else if (chore.type === 'group') {
      // For group chores, we need to use the original group_id for the endpoint path
      // but can send the new group_id in the payload for group changes
      const currentGroupId = originalChore?.group_id ?? chore.group_id;
      if (!currentGroupId) {
        throw new Error('Missing group_id for group chore update')
      }
      const response = await api.put(
        API_ENDPOINTS.CHORES.GROUP_CHORE_BY_ID(currentGroupId, choreId),
        chore,
      )
      return response.data
    } else {
      throw new Error('Invalid chore type for chore update')
    }
  },

  async deleteChore(choreId: number, choreType: ChoreType, groupId?: number): Promise<void> {
    if (choreType === 'personal') {
      await api.delete(API_ENDPOINTS.CHORES.PERSONAL_BY_ID(choreId))
    } else if (choreType === 'group' && groupId) {
      await api.delete(API_ENDPOINTS.CHORES.GROUP_CHORE_BY_ID(groupId, choreId))
    } else {
      throw new Error('Invalid chore type or missing group_id for group chore deletion')
    }
  },

  async getPersonalChores(): Promise<Chore[]> {
    const response = await api.get(API_ENDPOINTS.CHORES.PERSONAL)
    return response.data
  },

  async createAssignment(assignment: ChoreAssignmentCreate): Promise<ChoreAssignment> {
    const response = await api.post(API_ENDPOINTS.CHORES.ASSIGNMENTS_BASE, assignment)
    return response.data
  },

  async getMyAssignments(includeCompleted: boolean = false): Promise<ChoreAssignment[]> {
    const response = await api.get(API_ENDPOINTS.CHORES.MY_ASSIGNMENTS(includeCompleted))
    return response.data
  },

  async getChoreAssignments(choreId: number): Promise<ChoreAssignment[]> {
    const response = await api.get(API_ENDPOINTS.CHORES.ASSIGNMENTS(choreId))
    return response.data
  },

  async updateAssignment(assignmentId: number, update: ChoreAssignmentUpdate): Promise<ChoreAssignment> {
    const response = await apiClient.put(API_ENDPOINTS.CHORES.ASSIGNMENT_BY_ID(assignmentId), update)
    return response.data
  },

  async deleteAssignment(assignmentId: number): Promise<void> {
    await api.delete(API_ENDPOINTS.CHORES.ASSIGNMENT_BY_ID(assignmentId))
  },

  async completeAssignment(assignmentId: number): Promise<ChoreAssignment> {
    const response = await api.patch(API_ENDPOINTS.CHORES.ASSIGNMENT_COMPLETE(assignmentId))
    return response.data
  },

  async _original_updateGroupChore(
    groupId: number,
    choreId: number,
    chore: ChoreUpdate,
  ): Promise<Chore> {
    const response = await api.put(API_ENDPOINTS.CHORES.GROUP_CHORE_BY_ID(groupId, choreId), chore)
    return response.data
  },

  async _original_deleteGroupChore(groupId: number, choreId: number): Promise<void> {
    await api.delete(API_ENDPOINTS.CHORES.GROUP_CHORE_BY_ID(groupId, choreId))
  },

  async _updatePersonalChore(choreId: number, chore: ChoreUpdate): Promise<Chore> {
    const response = await api.put(API_ENDPOINTS.CHORES.PERSONAL_BY_ID(choreId), chore)
    return response.data
  },

  async _deletePersonalChore(choreId: number): Promise<void> {
    await api.delete(API_ENDPOINTS.CHORES.PERSONAL_BY_ID(choreId))
  },

  async getChoreHistory(choreId: number): Promise<ChoreHistory[]> {
    const response = await apiClient.get(API_ENDPOINTS.CHORES.HISTORY(choreId))
    return response.data
  },
}
