import type { LeagueVisibilityType } from '../../domain/value-objects/LeagueVisibility';
import type { StewardingDecisionMode } from '../../domain/entities/League';

export type LeagueStructureMode = 'solo' | 'fixedTeams';

/**
 * League visibility determines public visibility and ranking status.
 * - 'ranked': Public, competitive, affects driver ratings. Requires min 10 drivers.
 * - 'unranked': Private, casual with friends. No rating impact. Any number of drivers.
 *
 * For backward compatibility, 'public'/'private' are also supported in the form,
 * but the domain uses 'ranked'/'unranked'.
 */
export type LeagueVisibilityFormValue = LeagueVisibilityType | 'public' | 'private';

export interface LeagueStructureFormDTO {
  mode: LeagueStructureMode;
  maxDrivers: number;
  maxTeams?: number;
  driversPerTeam?: number;
  multiClassEnabled?: boolean;
}

export interface LeagueChampionshipsFormDTO {
  enableDriverChampionship: boolean;
  enableTeamChampionship: boolean;
  enableNationsChampionship: boolean;
  enableTrophyChampionship: boolean;
}

export interface LeagueScoringFormDTO {
  patternId?: string; // e.g. 'sprint-main-driver', 'club-ladder-solo'
  // For now, keep customScoring optional and simple:
  customScoringEnabled?: boolean;
}

export interface LeagueDropPolicyFormDTO {
  strategy: 'none' | 'bestNResults' | 'dropWorstN';
  n?: number;
}

export interface LeagueTimingsFormDTO {
  practiceMinutes?: number;
  qualifyingMinutes: number;
  sprintRaceMinutes?: number;
  mainRaceMinutes: number;
  sessionCount: number;
  roundsPlanned?: number;

  seasonStartDate?: string; // ISO date YYYY-MM-DD
  seasonEndDate?: string; // ISO date YYYY-MM-DD
  raceStartTime?: string; // "HH:MM" 24h
  timezoneId?: string; // IANA ID, e.g. "Europe/Berlin", or "track" for track local time
  recurrenceStrategy?: 'weekly' | 'everyNWeeks' | 'monthlyNthWeekday';
  intervalWeeks?: number;
  weekdays?: import('../../domain/types/Weekday').Weekday[];
  monthlyOrdinal?: 1 | 2 | 3 | 4;
  monthlyWeekday?: import('../../domain/types/Weekday').Weekday;
}

/**
 * Stewarding configuration for protests and penalties.
 */
export interface LeagueStewardingFormDTO {
  /**
   * How protest decisions are made
   */
  decisionMode: StewardingDecisionMode;
  /**
   * Number of votes required to uphold/reject a protest
   * Used with steward_vote, member_vote, steward_veto, member_veto modes
   */
  requiredVotes?: number;
  /**
   * Whether to require a defense from the accused before deciding
   */
  requireDefense: boolean;
  /**
   * Time limit (hours) for accused to submit defense
   */
  defenseTimeLimit: number;
  /**
   * Time limit (hours) for voting to complete
   */
  voteTimeLimit: number;
  /**
   * Time limit (hours) after race ends when protests can be filed
   */
  protestDeadlineHours: number;
  /**
   * Time limit (hours) after race ends when stewarding is closed
   */
  stewardingClosesHours: number;
  /**
   * Whether to notify the accused when a protest is filed
   */
  notifyAccusedOnProtest: boolean;
  /**
   * Whether to notify eligible voters when a vote is required
   */
  notifyOnVoteRequired: boolean;
}

export interface LeagueConfigFormModel {
  leagueId?: string; // present for admin, omitted for create
  basics: {
    name: string;
    description?: string;
    /**
     * League visibility/ranking mode.
     * - 'ranked' (or legacy 'public'): Competitive, public, affects ratings. Min 10 drivers.
     * - 'unranked' (or legacy 'private'): Casual with friends, no rating impact.
     */
    visibility: LeagueVisibilityFormValue;
    gameId: string;
    /**
     * League logo as base64 data URL (optional).
     * Format: data:image/png;base64,... or data:image/jpeg;base64,...
     */
    logoDataUrl?: string;
  };
  structure: LeagueStructureFormDTO;
  championships: LeagueChampionshipsFormDTO;
  scoring: LeagueScoringFormDTO;
  dropPolicy: LeagueDropPolicyFormDTO;
  timings: LeagueTimingsFormDTO;
  stewarding: LeagueStewardingFormDTO;
}

/**
 * Helper to normalize visibility values to new terminology.
 * Maps 'public' -> 'ranked' and 'private' -> 'unranked'.
 */
export function normalizeVisibility(value: LeagueVisibilityFormValue): LeagueVisibilityType {
  if (value === 'public' || value === 'ranked') return 'ranked';
  return 'unranked';
}

/**
 * Helper to convert new terminology to legacy for backward compatibility.
 * Maps 'ranked' -> 'public' and 'unranked' -> 'private'.
 */
export function toLegacyVisibility(value: LeagueVisibilityFormValue): 'public' | 'private' {
  if (value === 'ranked' || value === 'public') return 'public';
  return 'private';
}