import type {
  AdminAuditEntriesResponse,
  AdminArchivedWinnerItem,
  AdminAuditQueryOptions,
  AdminCandidateDeletePreview,
  AdminDashboardResponse,
  AdminOptionalFeatureSettingsResponse,
  AdminOperationalSettingsResponse,
  AdminNominationLinkBlacklistResponse,
  AdminRiskFlagsResponse,
  AdminRiskQueryOptions,
  AdminRiskRulesResponse,
  AdminSeasonDetailResponse,
  AdminSeasonListItem,
  AdminShowactApplicationItem,
  AdminSiteSettingsResponse,
  AdminSponsorItem,
  AdminTeamResponse,
  AdminTrackingRulesResponse,
  AdminWorkflowRulesResponse,
  ApproveNominationPayload,
  AddNominationLinkBlacklistEntryPayload,
  BulkResolveRiskFlagsPayload,
  CreateTeamMemberPayload,
  CreateSeasonPayload,
  ReopenRejectedNominationPayload,
  RejectNominationPayload,
  ResolveRiskFlagPayload,
  SetAwardResultPayload,
  UpdateNominationTrackingReviewPayload,
  UpdateSeasonSubcategoryTemplatesPayload,
  TeamMemberPasswordResponse,
  UpdateClipStatusPayload,
  UpdateOptionalFeatureSettingsPayload,
  UpdateOperationalSettingsPayload,
  UpdateRiskRulesPayload,
  UpdateShowactStatusPayload,
  UpdateNominationLinkBlacklistPayload,
  UpdateSeasonPayload,
  UpdateSiteSettingsPayload,
  UpdateTrackingReviewNotesPayload,
  UpdateTrackingRulesPayload,
  UpdateTrackingSourcePayload,
  UpdateTeamMemberPayload,
  UpdateTeamRolesPayload,
  UpdateWorkflowRulesPayload,
  UpsertCandidatePayload,
  UpsertArchivedWinnerPayload,
  UpsertCategoryPayload,
  UpsertCategoryGroupPayload,
  UpsertSponsorPayload,
} from '../../types/awards'
import { requestJson } from '../http'
import { jsonRequest } from './requestOptions'

function buildAdminAuditEntryParams(options: AdminAuditQueryOptions = {}) {
  const params = new URLSearchParams({ limit: String(options.limit ?? 100) })
  const trimmedQuery = options.query?.trim()
  const trimmedAdmin = options.admin?.trim()
  const trimmedAction = options.action?.trim()
  const trimmedEntityType = options.entityType?.trim()

  if (trimmedQuery) params.set('query', trimmedQuery)
  if (trimmedAdmin) params.set('admin', trimmedAdmin)
  if (trimmedAction) params.set('action', trimmedAction)
  if (trimmedEntityType) params.set('entityType', trimmedEntityType)
  if (options.from) params.set('from', options.from)
  if (options.to) params.set('to', options.to)
  if (options.cursor) params.set('cursor', options.cursor)

  return params
}

export const adminApi = {
  getAdminDashboard: (seasonId?: number | null) => {
    const params = new URLSearchParams()
    if (seasonId) {
      params.set('seasonId', String(seasonId))
    }
    const query = params.toString()

    return requestJson<AdminDashboardResponse>(`/api/admin/dashboard${query ? `?${query}` : ''}`)
  },
  getAdminAuditEntriesPage: (options: AdminAuditQueryOptions = {}) =>
    requestJson<AdminAuditEntriesResponse>(`/api/admin/audit-entries?${buildAdminAuditEntryParams(options).toString()}`),
  getAdminAuditEntries: (limit = 200, query = '') => {
    const params = buildAdminAuditEntryParams({ limit, query })
    return requestJson<AdminAuditEntriesResponse>(`/api/admin/audit-entries?${params.toString()}`)
      .then((response) => response.items)
  },
  getAdminRiskFlagsPage: (options: AdminRiskQueryOptions = {}) => {
    const params = new URLSearchParams({
      limit: String(options.limit ?? 25),
      offset: String(options.offset ?? 0),
      status: options.status ?? 'open',
    })
    if (options.severity) {
      params.set('severity', options.severity)
    }
    const trimmedQuery = options.query?.trim()
    if (trimmedQuery) {
      params.set('query', trimmedQuery)
    }
    if (options.reviewedOnly) {
      params.set('reviewedOnly', 'true')
    }

    return requestJson<AdminRiskFlagsResponse>(`/api/admin/risk-flags?${params.toString()}`)
  },
  getAdminRiskFlags: (limit = 200, status = 'open', query = '') =>
    adminApi.getAdminRiskFlagsPage({ limit, status, query }).then((response) => response.items),
  getAdminRiskRules: () => requestJson<AdminRiskRulesResponse>('/api/admin/risk-rules'),
  updateAdminRiskRules: (payload: UpdateRiskRulesPayload) =>
    requestJson<AdminRiskRulesResponse>('/api/admin/risk-rules', jsonRequest('PUT', payload)),
  getAdminWorkflowRules: (seasonId: number) => requestJson<AdminWorkflowRulesResponse>(`/api/admin/seasons/${seasonId}/workflow-rules`),
  updateAdminWorkflowRules: (seasonId: number, payload: UpdateWorkflowRulesPayload) =>
    requestJson<AdminWorkflowRulesResponse>(`/api/admin/seasons/${seasonId}/workflow-rules`, jsonRequest('PUT', payload)),
  getAdminTrackingRules: () => requestJson<AdminTrackingRulesResponse>('/api/admin/tracking-rules'),
  updateAdminTrackingRules: (payload: UpdateTrackingRulesPayload) =>
    requestJson<AdminTrackingRulesResponse>('/api/admin/tracking-rules', jsonRequest('PUT', payload)),
  updateAdminTrackingSource: (payload: UpdateTrackingSourcePayload) =>
    requestJson<AdminTrackingRulesResponse>('/api/admin/tracking-rules/source', jsonRequest('PUT', payload)),
  updateAdminTrackingReviewNotes: (payload: UpdateTrackingReviewNotesPayload) =>
    requestJson<AdminTrackingRulesResponse>('/api/admin/tracking-rules/notes', jsonRequest('PUT', payload)),
  getAdminSeasons: () => requestJson<AdminSeasonListItem[]>('/api/admin/seasons'),
  getAdminSeasonDetail: (seasonId: number) =>
    requestJson<AdminSeasonDetailResponse>(`/api/admin/seasons/${seasonId}`),
  getAdminShowactApplications: (seasonId: number) =>
    requestJson<AdminShowactApplicationItem[]>(`/api/admin/seasons/${seasonId}/showacts`),
  updateAdminShowactStatus: (applicationId: number, payload: UpdateShowactStatusPayload) =>
    requestJson<{ saved: boolean; application: AdminShowactApplicationItem }>(
      `/api/admin/showacts/${applicationId}/status`,
      jsonRequest('POST', payload),
    ),
  deleteAdminShowactApplication: (applicationId: number) =>
    requestJson<{ deleted: boolean; applicationId: number }>(`/api/admin/showacts/${applicationId}`, { method: 'DELETE' }),
  getAdminSponsors: (seasonId: number) =>
    requestJson<AdminSponsorItem[]>(`/api/admin/seasons/${seasonId}/sponsors`),
  createAdminSponsor: (seasonId: number, payload: UpsertSponsorPayload) =>
    requestJson<{ saved: boolean; sponsor: AdminSponsorItem }>(`/api/admin/seasons/${seasonId}/sponsors`, jsonRequest('POST', payload)),
  updateAdminSponsor: (sponsorId: number, payload: UpsertSponsorPayload) =>
    requestJson<{ saved: boolean; sponsor: AdminSponsorItem }>(`/api/admin/sponsors/${sponsorId}`, jsonRequest('PUT', payload)),
  deleteAdminSponsor: (sponsorId: number) =>
    requestJson<{ deleted: boolean; sponsorId: number }>(`/api/admin/sponsors/${sponsorId}`, { method: 'DELETE' }),
  getAdminArchivedWinners: () => requestJson<AdminArchivedWinnerItem[]>('/api/admin/archived-winners'),
  createAdminArchivedWinner: (payload: UpsertArchivedWinnerPayload) =>
    requestJson<{ saved: boolean; entry: AdminArchivedWinnerItem }>('/api/admin/archived-winners', jsonRequest('POST', payload)),
  updateAdminArchivedWinner: (archivedWinnerId: number, payload: UpsertArchivedWinnerPayload) =>
    requestJson<{ saved: boolean; entry: AdminArchivedWinnerItem }>(
      `/api/admin/archived-winners/${archivedWinnerId}`,
      jsonRequest('PUT', payload),
    ),
  deleteAdminArchivedWinner: (archivedWinnerId: number) =>
    requestJson<{ deleted: boolean; archivedWinnerId: number }>(`/api/admin/archived-winners/${archivedWinnerId}`, { method: 'DELETE' }),
  getAdminSiteSettings: () => requestJson<AdminSiteSettingsResponse>('/api/admin/site-settings'),
  uploadAdminHostImage: (file: File) => {
    const formData = new FormData()
    formData.append('file', file)
    return requestJson<AdminSiteSettingsResponse>('/api/admin/site-settings/host-image', {
      method: 'POST',
      body: formData,
    })
  },
  getAdminOptionalFeatureSettings: () =>
    requestJson<AdminOptionalFeatureSettingsResponse>('/api/admin/optional-feature-settings'),
  updateAdminOptionalFeatureSettings: (payload: UpdateOptionalFeatureSettingsPayload) =>
    requestJson<AdminOptionalFeatureSettingsResponse>('/api/admin/optional-feature-settings', jsonRequest('PUT', payload)),
  getAdminOperationalSettings: () =>
    requestJson<AdminOperationalSettingsResponse>('/api/admin/operational-settings'),
  getAdminTeam: () => requestJson<AdminTeamResponse>('/api/admin/team'),
  createAdminTeamMember: (payload: CreateTeamMemberPayload) =>
    requestJson<TeamMemberPasswordResponse>('/api/admin/team/members', jsonRequest('POST', payload)),
  updateAdminTeamMember: (memberId: number, payload: UpdateTeamMemberPayload) =>
    requestJson<{ saved: boolean; member: AdminTeamResponse['members'][number] }>(
      `/api/admin/team/members/${memberId}`,
      jsonRequest('PUT', payload),
    ),
  resetAdminTeamMemberPassword: (memberId: number) =>
    requestJson<TeamMemberPasswordResponse>(`/api/admin/team/members/${memberId}/reset-password`, jsonRequest('POST', {})),
  deleteAdminTeamMember: (memberId: number) =>
    requestJson<{ deleted: boolean; memberId: number }>(`/api/admin/team/members/${memberId}`, { method: 'DELETE' }),
  updateAdminTeamRoles: (payload: UpdateTeamRolesPayload) =>
    requestJson<{ saved: boolean; roles: AdminTeamResponse['roles'] }>('/api/admin/team/roles', jsonRequest('PUT', payload)),
  createAdminSeason: (payload: CreateSeasonPayload) =>
    requestJson<{ saved: boolean; seasonId: number }>('/api/admin/seasons', jsonRequest('POST', payload)),
  updateAdminSeason: (seasonId: number, payload: UpdateSeasonPayload) =>
    requestJson<{ saved: boolean; seasonId: number }>(`/api/admin/seasons/${seasonId}`, jsonRequest('PUT', payload)),
  deleteAdminSeason: (seasonId: number) =>
    requestJson<{ deleted: boolean; seasonId: number; year: number }>(`/api/admin/seasons/${seasonId}`, {
      method: 'DELETE',
    }),
  updateAdminSiteSettings: (payload: UpdateSiteSettingsPayload) =>
    requestJson<{ saved: boolean }>('/api/admin/site-settings', jsonRequest('PUT', payload)),
  updateAdminOperationalSettings: (payload: UpdateOperationalSettingsPayload) =>
    requestJson<{ saved: boolean; demoLoginPasswordSet: boolean; twitchClientSecretSet: boolean }>('/api/admin/operational-settings', jsonRequest('PUT', payload)),
  createAdminCategory: (seasonId: number, payload: UpsertCategoryPayload) =>
    requestJson<{ saved: boolean; categoryId: number }>(`/api/admin/seasons/${seasonId}/categories`, jsonRequest('POST', payload)),
  updateAdminCategory: (categoryId: number, payload: UpsertCategoryPayload) =>
    requestJson<{ saved: boolean; categoryId: number }>(`/api/admin/categories/${categoryId}`, jsonRequest('PUT', payload)),
  deleteAdminCategory: (categoryId: number) =>
    requestJson<{ deleted: boolean; categoryId: number }>(`/api/admin/categories/${categoryId}`, {
      method: 'DELETE',
    }),
  updateAdminSeasonSubcategoryTemplates: (seasonId: number, payload: UpdateSeasonSubcategoryTemplatesPayload) =>
    requestJson<{ saved: boolean; seasonId: number; templateCount: number }>(
      `/api/admin/seasons/${seasonId}/subcategory-templates`,
      jsonRequest('PUT', payload),
    ),
  createAdminCategoryGroup: (seasonId: number, payload: UpsertCategoryGroupPayload) =>
    requestJson<{ saved: boolean; seasonId: number; groupName: string }>(
      `/api/admin/seasons/${seasonId}/category-groups`,
      jsonRequest('POST', payload),
    ),
  updateAdminCategoryGroup: (seasonId: number, groupName: string, payload: UpsertCategoryGroupPayload) =>
    requestJson<{ saved: boolean; seasonId: number; groupName: string }>(
      `/api/admin/seasons/${seasonId}/category-groups/${encodeURIComponent(groupName)}`,
      jsonRequest('PUT', payload),
    ),
  deleteAdminCategoryGroup: (seasonId: number, groupName: string) =>
    requestJson<{ deleted: boolean; seasonId: number; groupName: string }>(
      `/api/admin/seasons/${seasonId}/category-groups/${encodeURIComponent(groupName)}`,
      { method: 'DELETE' },
    ),
  createAdminCandidate: (seasonId: number, payload: UpsertCandidatePayload) =>
    requestJson<{ saved: boolean; candidateId: number }>(`/api/admin/seasons/${seasonId}/candidates`, jsonRequest('POST', payload)),
  updateAdminCandidate: (candidateId: number, payload: UpsertCandidatePayload) =>
    requestJson<{ saved: boolean; candidateId: number }>(`/api/admin/candidates/${candidateId}`, jsonRequest('PUT', payload)),
  getAdminCandidateDeletePreview: (candidateId: number) =>
    requestJson<AdminCandidateDeletePreview>(`/api/admin/candidates/${candidateId}/delete-preview`),
  deleteAdminCandidate: (candidateId: number) =>
    requestJson<{ deleted: boolean; candidateId: number }>(`/api/admin/candidates/${candidateId}`, {
      method: 'DELETE',
    }),
  deleteAdminClip: (clipId: number) =>
    requestJson<{ deleted: boolean; clipId: number }>(`/api/admin/clips/${clipId}`, {
      method: 'DELETE',
    }),
  updateAdminClipStatus: (clipId: number, payload: UpdateClipStatusPayload) =>
    requestJson<{ saved: boolean; clipId: number; status: string }>(`/api/admin/clips/${clipId}/status`, jsonRequest('POST', payload)),
  setAdminResult: (seasonId: number, payload: SetAwardResultPayload) =>
    requestJson<{ saved: boolean; resultId: number; seasonId: number; categoryId: number; candidateId: number }>(
      `/api/admin/seasons/${seasonId}/results`,
      jsonRequest('POST', payload),
    ),
  deleteAdminResult: (resultId: number) =>
    requestJson<{ deleted: boolean; resultId: number }>(`/api/admin/results/${resultId}`, {
      method: 'DELETE',
    }),
  publishAdminWinners: (seasonId: number) =>
    requestJson<{ saved: boolean; seasonId: number; winnersPublishedAt: string | null; winnersPublishedByTwitchId: string | null }>(
      `/api/admin/seasons/${seasonId}/winners/publish`,
      jsonRequest('POST', {}),
    ),
  unpublishAdminWinners: (seasonId: number) =>
    requestJson<{ saved: boolean; seasonId: number; winnersPublishedAt: string | null; winnersPublishedByTwitchId: string | null }>(
      `/api/admin/seasons/${seasonId}/winners/unpublish`,
      jsonRequest('POST', {}),
    ),
  approveAdminNomination: (nominationId: number, payload: ApproveNominationPayload) =>
    requestJson<{ saved: boolean; nominationId: number; candidateId: number; created: boolean }>(
      `/api/admin/nominations/${nominationId}/approve`,
      jsonRequest('POST', payload),
    ),
  rejectAdminNomination: (nominationId: number, payload: RejectNominationPayload) =>
    requestJson<{ saved: boolean; nominationId: number; rejected: boolean }>(
      `/api/admin/nominations/${nominationId}/reject`,
      jsonRequest('POST', payload),
    ),
  reopenRejectedAdminNomination: (nominationId: number, payload: ReopenRejectedNominationPayload = {}) =>
    requestJson<{ saved: boolean; nominationId: number; reopened: boolean }>(
      `/api/admin/nominations/${nominationId}/reopen`,
      jsonRequest('POST', payload),
    ),
  updateNominationTrackingReview: (nominationId: number, payload: UpdateNominationTrackingReviewPayload) =>
    requestJson<{ saved: boolean; nominationId: number; status: string }>(
      `/api/admin/nominations/${nominationId}/tracking-review`,
      jsonRequest('POST', payload),
    ),
  getAdminNominationLinkBlacklist: () =>
    requestJson<AdminNominationLinkBlacklistResponse>('/api/admin/nominations/link-blacklist'),
  updateAdminNominationLinkBlacklist: (payload: UpdateNominationLinkBlacklistPayload) =>
    requestJson<AdminNominationLinkBlacklistResponse>('/api/admin/nominations/link-blacklist', jsonRequest('PUT', payload)),
  addAdminNominationLinkBlacklistEntry: (payload: AddNominationLinkBlacklistEntryPayload) =>
    requestJson<AdminNominationLinkBlacklistResponse>('/api/admin/nominations/link-blacklist', jsonRequest('POST', payload)),
  resolveRiskFlag: (riskFlagId: number, payload: ResolveRiskFlagPayload) =>
    requestJson<{ saved: boolean; riskFlagId: number; status: string }>(
      `/api/admin/risk-flags/${riskFlagId}/resolve`,
      jsonRequest('POST', payload),
    ),
  bulkResolveRiskFlags: (payload: BulkResolveRiskFlagsPayload) =>
    requestJson<{ saved: boolean; count: number; status: string }>(
      '/api/admin/risk-flags/bulk-resolve',
      jsonRequest('POST', payload),
    ),
}
