// User types
export type UserRole = 'user' | 'admin'

// Public user info (visible to other users)
export interface UserPublic {
  id: number
  nickname: string
  avatar_url: string | null
  role: UserRole
  telegram_avatar_url: string | null
  created_at: string
  // Equipped cosmetics
  equipped_frame: ShopItemPublic | null
  equipped_title: ShopItemPublic | null
  equipped_name_color: ShopItemPublic | null
  equipped_background: ShopItemPublic | null
}

// Full user info (only for own profile from /auth/me)
export interface User extends UserPublic {
  login?: string  // Only visible to self
  telegram_id?: number | null  // Only visible to self
  telegram_username?: string | null  // Only visible to self
  telegram_first_name?: string | null  // Only visible to self
  telegram_last_name?: string | null  // Only visible to self
  // Notification settings
  notify_events?: boolean
  notify_disputes?: boolean
  notify_moderation?: boolean
}

// Notification settings
export interface NotificationSettings {
  notify_events: boolean
  notify_disputes: boolean
  notify_moderation: boolean
}

export interface NotificationSettingsUpdate {
  notify_events?: boolean
  notify_disputes?: boolean
  notify_moderation?: boolean
}

export interface TokenResponse {
  access_token: string
  token_type: string
  user: User
}

// Login response (may require 2FA for admins)
export interface LoginResponse {
  access_token?: string | null
  token_type: string
  user?: User | null
  requires_2fa: boolean
  two_factor_session_id?: number | null
}

// Marathon types
export type MarathonStatus = 'preparing' | 'active' | 'finished'
export type ParticipantRole = 'participant' | 'organizer'
export type GameProposalMode = 'all_participants' | 'organizer_only'

export interface ParticipantInfo {
  id: number
  role: ParticipantRole
  total_points: number
  current_streak: number
  drop_count: number
  joined_at: string
}

export interface ParticipantWithUser extends ParticipantInfo {
  user: User
}

export interface Marathon {
  id: number
  title: string
  description: string | null
  creator: User
  status: MarathonStatus
  invite_code: string
  is_public: boolean
  game_proposal_mode: GameProposalMode
  auto_events_enabled: boolean
  allow_consumables: boolean
  cover_url: string | null
  start_date: string | null
  end_date: string | null
  participants_count: number
  games_count: number
  created_at: string
  my_participation: ParticipantInfo | null
}

export interface MarathonListItem {
  id: number
  title: string
  status: MarathonStatus
  is_public: boolean
  cover_url: string | null
  participants_count: number
  start_date: string | null
  end_date: string | null
}

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

export interface MarathonUpdate {
  title?: string
  description?: string
  start_date?: string
  is_public?: boolean
  game_proposal_mode?: GameProposalMode
  auto_events_enabled?: boolean
}

export interface MarathonPublicInfo {
  id: number
  title: string
  description: string | null
  status: MarathonStatus
  cover_url: string | null
  participants_count: number
  creator_nickname: string
}

export interface LeaderboardEntry {
  rank: number
  user: User
  total_points: number
  current_streak: number
  completed_count: number
  dropped_count: number
}

// Game types
export type GameStatus = 'pending' | 'approved' | 'rejected'
export type GameType = 'challenges' | 'playthrough'

export interface PlaythroughInfo {
  description: string
  points: number
  proof_type: ProofType
  proof_hint: string | null
}

export interface Game {
  id: number
  title: string
  cover_url: string | null
  download_url: string
  genre: string | null
  status: GameStatus
  proposed_by: User | null
  approved_by: User | null
  challenges_count: number
  created_at: string
  // Game type fields
  game_type: GameType
  playthrough_points: number | null
  playthrough_description: string | null
  playthrough_proof_type: ProofType | null
  playthrough_proof_hint: string | null
}

export interface GameShort {
  id: number
  title: string
  cover_url: string | null
  download_url?: string
  game_type?: GameType
}

export interface ExiledGame {
  id: number
  game_id: number
  game_title: string
  exiled_at: string
  exiled_by: 'user' | 'organizer' | 'admin'
  reason: string | null
}

export interface AvailableGamesCount {
  available: number
  total: number
}

// Challenge types
export type ChallengeType =
  | 'completion'
  | 'no_death'
  | 'speedrun'
  | 'collection'
  | 'achievement'
  | 'challenge_run'
  | 'score_attack'
  | 'time_trial'

export type Difficulty = 'easy' | 'medium' | 'hard'
export type ProofType = 'screenshot' | 'video' | 'steam'

export type ChallengeStatus = 'pending' | 'approved' | 'rejected'

export interface ProposedByUser {
  id: number
  nickname: string
}

export interface Challenge {
  id: number
  game: GameShort
  title: string
  description: string
  type: ChallengeType
  difficulty: Difficulty
  points: number
  estimated_time: number | null
  proof_type: ProofType
  proof_hint: string | null
  is_generated: boolean
  created_at: string
  status: ChallengeStatus
  proposed_by: ProposedByUser | null
}

export interface ChallengePreview {
  game_id: number
  game_title: string
  title: string
  description: string
  type: string
  difficulty: Difficulty
  points: number
  estimated_time: number | null
  proof_type: ProofType
  proof_hint: string | null
}

export interface ChallengesPreviewResponse {
  challenges: ChallengePreview[]
}

// Assignment types
export type AssignmentStatus = 'active' | 'completed' | 'dropped' | 'returned'
export type BonusAssignmentStatus = 'pending' | 'completed'

export interface BonusAssignment {
  id: number
  challenge: Challenge
  status: BonusAssignmentStatus
  proof_url: string | null
  proof_image_url: string | null  // Legacy, for backward compatibility
  proof_files?: ProofFile[]  // Multiple uploaded files
  proof_comment: string | null
  points_earned: number
  completed_at: string | null
  can_dispute?: boolean
  dispute?: Dispute | null
}

export interface Assignment {
  id: number
  challenge: Challenge | null  // null for playthrough
  game?: GameShort  // For playthrough
  is_playthrough?: boolean
  playthrough_info?: PlaythroughInfo  // For playthrough
  status: AssignmentStatus
  proof_url: string | null
  proof_comment: string | null
  points_earned: number
  streak_at_completion: number | null
  tracked_time_minutes?: number  // Time tracked by desktop app (for playthroughs)
  started_at: string
  completed_at: string | null
  drop_penalty: number
  bonus_challenges?: BonusAssignment[]  // For playthrough
  event_type?: EventType  // Event active when assignment was created
}

export interface SpinResult {
  assignment_id: number
  game: Game
  challenge: Challenge | null  // null for playthrough
  is_playthrough?: boolean
  playthrough_info?: PlaythroughInfo  // For playthrough
  bonus_challenges?: Challenge[]  // Available bonus challenges for playthrough
  can_drop: boolean
  drop_penalty: number
  event_type?: EventType  // Event active during spin
}

export interface CompleteResult {
  points_earned: number
  streak_bonus: number
  total_points: number
  new_streak: number
}

export interface DropResult {
  penalty: number
  total_points: number
  new_drop_count: number
}

export interface DroppedAssignment {
  id: number
  challenge: Challenge
  dropped_at: string
}

export interface SwapCandidate {
  participant_id: number
  user: User
  is_playthrough: boolean
  // Challenge fields (used when is_playthrough=false)
  challenge_title: string | null
  challenge_description: string | null
  challenge_points: number | null
  challenge_difficulty: Difficulty | null
  // Playthrough fields (used when is_playthrough=true)
  playthrough_description: string | null
  playthrough_points: number | null
  // Common field
  game_title: string
}

// Two-sided swap confirmation types
export type SwapRequestStatus = 'pending' | 'accepted' | 'declined' | 'cancelled'

export interface SwapRequestChallengeInfo {
  is_playthrough: boolean
  // Challenge fields (used when is_playthrough=false)
  title: string | null
  description: string | null
  points: number | null
  difficulty: string | null
  // Playthrough fields (used when is_playthrough=true)
  playthrough_description: string | null
  playthrough_points: number | null
  // Common field
  game_title: string
}

export interface SwapRequestItem {
  id: number
  status: SwapRequestStatus
  from_user: User
  to_user: User
  from_challenge: SwapRequestChallengeInfo
  to_challenge: SwapRequestChallengeInfo
  created_at: string
  responded_at: string | null
}

export interface MySwapRequests {
  incoming: SwapRequestItem[]
  outgoing: SwapRequestItem[]
}

// Common Enemy leaderboard
export interface CommonEnemyLeaderboardEntry {
  participant_id: number
  user: User
  completed_at: string | null
  rank: number | null
  bonus_points: number
}

// Event Assignment (Common Enemy)
export interface EventAssignment {
  assignment: Assignment | null
  event_id: number | null
  challenge_id: number | null
  is_completed: boolean
}

// Activity types
export type ActivityType =
  | 'join'
  | 'spin'
  | 'complete'
  | 'drop'
  | 'start_marathon'
  | 'finish_marathon'
  | 'add_game'
  | 'approve_game'
  | 'reject_game'
  | 'event_start'
  | 'event_end'
  | 'swap'
  | 'rematch'

export interface Activity {
  id: number
  type: ActivityType
  user: User
  data: Record<string, unknown> | null
  created_at: string
}

export interface FeedResponse {
  items: Activity[]
  total: number
  has_more: boolean
}

// Event types
export type EventType =
  | 'golden_hour'
  | 'common_enemy'
  | 'double_risk'
  | 'jackpot'
  | 'swap'
  | 'game_choice'

export interface MarathonEvent {
  id: number
  type: EventType
  start_time: string
  end_time: string | null
  is_active: boolean
  created_by: User | null
  data: Record<string, unknown> | null
  created_at: string
}

export interface EventEffects {
  points_multiplier: number
  drop_free: boolean
  special_action: string | null
  description: string
}

export interface ActiveEvent {
  event: MarathonEvent | null
  effects: EventEffects
  time_remaining_seconds: number | null
}

export interface EventCreate {
  type: EventType
  duration_minutes?: number
  challenge_id?: number
}

export const EVENT_INFO: Record<EventType, { name: string; description: string; color: string }> = {
  golden_hour: {
    name: 'Золотой час',
    description: 'Все очки x1.5!',
    color: 'yellow',
  },
  common_enemy: {
    name: 'Общий враг',
    description: 'Все получают одинаковый челлендж. Первые 3 — бонус!',
    color: 'red',
  },
  double_risk: {
    name: 'Безопасная игра',
    description: 'Дропы бесплатны, но очки x0.5',
    color: 'purple',
  },
  jackpot: {
    name: 'Джекпот',
    description: 'Следующий спин — сложный челлендж с x3 очками!',
    color: 'green',
  },
  swap: {
    name: 'Обмен',
    description: 'Можно поменяться заданием с другим участником',
    color: 'blue',
  },
  game_choice: {
    name: 'Выбор игры',
    description: 'Выбери игру и один из 3 челленджей. Можно заменить задание без штрафа!',
    color: 'orange',
  },
}

// Game Choice types
export interface GameChoiceChallenge {
  id: number
  title: string
  description: string
  difficulty: Difficulty
  points: number
  estimated_time: number | null
  proof_type: ProofType
  proof_hint: string | null
}

export interface GameChoiceChallenges {
  game_id: number
  game_title: string
  challenges: GameChoiceChallenge[]
}

// Admin types
export interface AdminUser {
  id: number
  login: string
  nickname: string
  role: UserRole
  avatar_url: string | null
  telegram_id: number | null
  telegram_username: string | null
  marathons_count: number
  created_at: string
  is_banned: boolean
  banned_at: string | null
  banned_until: string | null  // null = permanent ban
  ban_reason: string | null
  // Notification settings
  notify_events: boolean
  notify_disputes: boolean
  notify_moderation: boolean
}

export interface AdminMarathon {
  id: number
  title: string
  status: MarathonStatus
  creator: User
  participants_count: number
  games_count: number
  start_date: string | null
  end_date: string | null
  created_at: string
  certification_status: string
  is_certified: boolean
}

export interface PlatformStats {
  users_count: number
  marathons_count: number
  games_count: number
  total_participations: number
}

// Admin action log types
export type AdminActionType =
  | 'user_ban'
  | 'user_unban'
  | 'user_role_change'
  | 'marathon_force_finish'
  | 'marathon_delete'
  | 'content_update'
  | 'broadcast_all'
  | 'broadcast_marathon'
  | 'admin_login'
  | 'admin_2fa_success'
  | 'admin_2fa_fail'

export interface AdminLog {
  id: number
  admin_id: number
  admin_nickname: string
  action: AdminActionType
  target_type: string
  target_id: number
  details: Record<string, unknown> | null
  ip_address: string | null
  created_at: string
}

export interface AdminLogsResponse {
  logs: AdminLog[]
  total: number
}

// Broadcast types
export interface BroadcastResponse {
  sent_count: number
  total_count: number
}

// Static content types
export interface StaticContent {
  id: number
  key: string
  title: string
  content: string
  updated_at: string
  created_at: string
}

// Dashboard stats
export interface DashboardStats {
  users_count: number
  banned_users_count: number
  marathons_count: number
  active_marathons_count: number
  games_count: number
  total_participations: number
  recent_logs: AdminLog[]
}

// Admin dispute
export interface AdminDispute {
  id: number
  assignment_id: number | null
  bonus_assignment_id: number | null
  marathon_id: number
  marathon_title: string
  challenge_title: string
  participant_nickname: string
  raised_by_nickname: string
  reason: string
  status: DisputeStatus
  votes_valid: number
  votes_invalid: number
  created_at: string
  expires_at: string
}

// Marathon organizer dispute
export interface MarathonDispute {
  id: number
  assignment_id: number | null
  bonus_assignment_id: number | null
  challenge_title: string
  participant_nickname: string
  raised_by_nickname: string
  reason: string
  status: DisputeStatus
  votes_valid: number
  votes_invalid: number
  created_at: string
  expires_at: string
}

// Dispute types
export type DisputeStatus = 'open' | 'pending_admin' | 'valid' | 'invalid'

export interface DisputeComment {
  id: number
  user: User
  text: string
  created_at: string
}

export interface DisputeVote {
  user: User
  vote: boolean // true = valid, false = invalid
  created_at: string
}

export interface Dispute {
  id: number
  raised_by: User
  reason: string
  status: DisputeStatus
  comments: DisputeComment[]
  votes: DisputeVote[]
  votes_valid: number
  votes_invalid: number
  my_vote: boolean | null
  expires_at: string
  created_at: string
  resolved_at: string | null
}

export interface ProofFile {
  id: number
  file_type: 'image' | 'video'
  order_index: number
  created_at: string
}

export interface AssignmentDetail {
  id: number
  challenge: Challenge | null  // null for playthrough
  game?: GameShort  // for playthrough
  is_playthrough: boolean
  playthrough_info?: PlaythroughInfo  // for playthrough
  participant: User
  status: AssignmentStatus
  proof_url: string | null
  proof_image_url: string | null  // Legacy, for backward compatibility
  proof_files: ProofFile[]  // Multiple uploaded files
  proof_comment: string | null
  points_earned: number
  streak_at_completion: number | null
  started_at: string
  completed_at: string | null
  can_dispute: boolean
  dispute: Dispute | null
  bonus_challenges?: BonusAssignment[]  // for playthrough
}

export interface ReturnedAssignment {
  id: number
  challenge: Challenge | null  // For challenge assignments
  is_playthrough: boolean
  game_id: number | null  // For playthrough assignments
  game_title: string | null
  game_cover_url: string | null
  original_completed_at: string
  dispute_reason: string
}

// Profile types
export interface UserStats {
  marathons_count: number
  wins_count: number
  completed_assignments: number
  total_points_earned: number
}

export interface UserProfilePublic {
  id: number
  nickname: string
  avatar_url: string | null
  telegram_avatar_url: string | null
  role: UserRole
  created_at: string
  stats: UserStats
  // Equipped cosmetics
  equipped_frame: ShopItemPublic | null
  equipped_title: ShopItemPublic | null
  equipped_name_color: ShopItemPublic | null
  equipped_background: ShopItemPublic | null
}

export interface PasswordChangeData {
  current_password: string
  new_password: string
}

// === Shop types ===

export type ShopItemType = 'frame' | 'title' | 'name_color' | 'background' | 'consumable'
export type ItemRarity = 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary'
export type ConsumableType = 'skip' | 'skip_exile' | 'boost' | 'wild_card' | 'lucky_dice' | 'copycat' | 'undo'

export interface ShopItemPublic {
  id: number
  code: string
  name: string
  item_type: ShopItemType
  rarity: ItemRarity
  asset_data: Record<string, unknown> | null
}

export interface ShopItem {
  id: number
  item_type: ShopItemType
  code: string
  name: string
  description: string | null
  price: number
  rarity: ItemRarity
  asset_data: Record<string, unknown> | null
  is_active: boolean
  available_from: string | null
  available_until: string | null
  stock_limit: number | null
  stock_remaining: number | null
  created_at: string
  is_available: boolean
  is_owned: boolean
  is_equipped: boolean
}

export interface InventoryItem {
  id: number
  item: ShopItem
  quantity: number
  equipped: boolean
  purchased_at: string
  expires_at: string | null
}

export interface PurchaseRequest {
  item_id: number
  quantity?: number
}

export interface PurchaseResponse {
  success: boolean
  item: ShopItem
  quantity: number
  total_cost: number
  new_balance: number
  message: string
}

export interface UseConsumableRequest {
  item_code: ConsumableType
  marathon_id: number
  assignment_id?: number
  game_id?: number  // Required for wild_card
  target_participant_id?: number  // Required for copycat
}

export interface UseConsumableResponse {
  success: boolean
  item_code: string
  remaining_quantity: number
  effect_description: string
  effect_data: Record<string, unknown> | null
}

export interface CoinTransaction {
  id: number
  amount: number
  transaction_type: string
  description: string | null
  reference_type: string | null
  reference_id: number | null
  created_at: string
}

export interface CoinsBalance {
  balance: number
  recent_transactions: CoinTransaction[]
}

export interface ConsumablesStatus {
  skips_available: number
  skip_exiles_available: number
  skips_used: number
  skips_remaining: number | null
  boosts_available: number
  has_active_boost: boolean
  boost_multiplier: number | null
  wild_cards_available: number
  lucky_dice_available: number
  has_lucky_dice: boolean
  lucky_dice_multiplier: number | null
  copycats_available: number
  undos_available: number
  can_undo: boolean
}

export interface UserCosmetics {
  frame: ShopItem | null
  title: ShopItem | null
  name_color: ShopItem | null
  background: ShopItem | null
}

// Certification types
export type CertificationStatus = 'none' | 'pending' | 'certified' | 'rejected'

export interface CertificationStatusResponse {
  marathon_id: number
  certification_status: CertificationStatus
  is_certified: boolean
  certification_requested_at: string | null
  certified_at: string | null
  certified_by_nickname: string | null
  rejection_reason: string | null
}

// Rarity colors for UI
export const RARITY_COLORS: Record<ItemRarity, { bg: string; border: string; text: string }> = {
  common: { bg: 'bg-gray-500/20', border: 'border-gray-500', text: 'text-gray-400' },
  uncommon: { bg: 'bg-green-500/20', border: 'border-green-500', text: 'text-green-400' },
  rare: { bg: 'bg-blue-500/20', border: 'border-blue-500', text: 'text-blue-400' },
  epic: { bg: 'bg-purple-500/20', border: 'border-purple-500', text: 'text-purple-400' },
  legendary: { bg: 'bg-yellow-500/20', border: 'border-yellow-500', text: 'text-yellow-400' },
}

export const RARITY_NAMES: Record<ItemRarity, string> = {
  common: 'Обычный',
  uncommon: 'Необычный',
  rare: 'Редкий',
  epic: 'Эпический',
  legendary: 'Легендарный',
}

export const ITEM_TYPE_NAMES: Record<ShopItemType, string> = {
  frame: 'Рамка',
  title: 'Титул',
  name_color: 'Цвет ника',
  background: 'Фон профиля',
  consumable: 'Расходуемое',
}

// === Promo Code types ===

export interface PromoCode {
  id: number
  code: string
  coins_amount: number
  max_uses: number | null
  uses_count: number
  is_active: boolean
  valid_from: string | null
  valid_until: string | null
  created_at: string
  created_by_nickname: string | null
}

export interface PromoCodeCreate {
  code?: string | null  // null = auto-generate
  coins_amount: number
  max_uses?: number | null
  valid_from?: string | null
  valid_until?: string | null
}

export interface PromoCodeUpdate {
  is_active?: boolean
  max_uses?: number | null
  valid_until?: string | null
}

export interface PromoCodeRedemption {
  id: number
  user: {
    id: number
    nickname: string
  }
  coins_awarded: number
  redeemed_at: string
}

export interface PromoCodeRedeemResponse {
  success: boolean
  coins_awarded: number
  new_balance: number
  message: string
}

// === Widget types ===

export interface WidgetToken {
  id: number
  token: string
  created_at: string
  expires_at: string | null
  is_active: boolean
  urls: {
    leaderboard: string
    current: string
    progress: string
  }
}

export interface WidgetLeaderboardEntry {
  rank: number
  nickname: string
  avatar_url: string | null
  total_points: number
  current_streak: number
  is_current_user: boolean
}

export interface WidgetLeaderboardData {
  entries: WidgetLeaderboardEntry[]
  current_user_rank: number | null
  total_participants: number
  marathon_title: string
}

export interface WidgetCurrentData {
  has_assignment: boolean
  game_title: string | null
  game_cover_url: string | null
  assignment_type: 'challenge' | 'playthrough' | null
  challenge_title: string | null
  challenge_description: string | null
  points: number | null
  difficulty: Difficulty | null
  bonus_completed: number | null
  bonus_total: number | null
}

export interface WidgetProgressData {
  nickname: string
  avatar_url: string | null
  rank: number
  total_points: number
  current_streak: number
  completed_count: number
  dropped_count: number
  marathon_title: string
}
