/**
 * League Wizard Service - Refactored to use API client
 * 
 * This service handles league creation wizard logic without direct core dependencies.
 */

import { apiClient } from '@/lib/apiClient';

export type WizardStep = 1 | 2 | 3 | 4 | 5 | 6 | 7;

export interface LeagueConfigFormModel {
  leagueId?: string;
  basics: {
    name: string;
    description?: string;
    visibility: 'public' | 'private' | 'unlisted';
    gameId: string;
  };
  structure: {
    mode: 'solo' | 'fixedTeams';
    maxDrivers?: number;
    maxTeams?: number;
    driversPerTeam?: number;
  };
  championships: {
    enableDriverChampionship: boolean;
    enableTeamChampionship: boolean;
    enableNationsChampionship: boolean;
    enableTrophyChampionship: boolean;
  };
  scoring: {
    patternId?: string;
    customScoringEnabled?: boolean;
  };
  dropPolicy: {
    strategy: 'none' | 'bestNResults' | 'dropWorstN';
    n?: number;
  };
  timings: {
    practiceMinutes?: number;
    qualifyingMinutes?: number;
    sprintRaceMinutes?: number;
    mainRaceMinutes?: number;
    sessionCount?: number;
    roundsPlanned?: number;
    raceDayOfWeek?: number;
    raceTimeUtc?: string;
  };
  stewarding: {
    decisionMode: 'owner_only' | 'admin_vote' | 'steward_panel';
    requiredVotes?: number;
    requireDefense: boolean;
    defenseTimeLimit: number;
    voteTimeLimit: number;
    protestDeadlineHours: number;
    stewardingClosesHours: number;
    notifyAccusedOnProtest: boolean;
    notifyOnVoteRequired: boolean;
  };
}

export interface WizardErrors {
  basics?: {
    name?: string;
    description?: string;
    visibility?: string;
  };
  structure?: {
    maxDrivers?: string;
    maxTeams?: string;
    driversPerTeam?: string;
  };
  timings?: {
    qualifyingMinutes?: string;
    mainRaceMinutes?: string;
    roundsPlanned?: string;
  };
  scoring?: {
    patternId?: string;
  };
  submit?: string;
}

/**
 * Step-scoped validation extracted from the React wizard.
 * Returns a fresh error bag for the given step based on the provided form model.
 */
export function validateLeagueWizardStep(
  form: LeagueConfigFormModel,
  step: WizardStep,
): WizardErrors {
  const errors: WizardErrors = {};

  // Step 1: Basics (name, description, game)
  if (step === 1) {
    const basicsErrors: NonNullable<WizardErrors['basics']> = {};
    
    // Basic name validation
    if (!form.basics.name || form.basics.name.trim().length === 0) {
      basicsErrors.name = 'League name is required';
    } else if (form.basics.name.length < 3) {
      basicsErrors.name = 'League name must be at least 3 characters';
    } else if (form.basics.name.length > 100) {
      basicsErrors.name = 'League name must be less than 100 characters';
    }
    
    // Description validation
    if (form.basics.description && form.basics.description.length > 500) {
      basicsErrors.description = 'Description must be less than 500 characters';
    }
    
    if (Object.keys(basicsErrors).length > 0) {
      errors.basics = basicsErrors;
    }
  }

  // Step 2: Visibility (ranked/unranked)
  if (step === 2) {
    const basicsErrors: NonNullable<WizardErrors['basics']> = {};
    
    if (!form.basics.visibility) {
      basicsErrors.visibility = 'Visibility is required';
    }
    
    if (Object.keys(basicsErrors).length > 0) {
      errors.basics = basicsErrors;
    }
  }

  // Step 3: Structure (solo vs teams)
  if (step === 3) {
    const structureErrors: NonNullable<WizardErrors['structure']> = {};
    
    if (form.structure.mode === 'solo') {
      if (!form.structure.maxDrivers || form.structure.maxDrivers <= 0) {
        structureErrors.maxDrivers =
          'Max drivers must be greater than 0 for solo leagues';
      } else if (form.structure.maxDrivers > 100) {
        structureErrors.maxDrivers = 'Max drivers cannot exceed 100';
      }
    } else if (form.structure.mode === 'fixedTeams') {
      if (!form.structure.maxTeams || form.structure.maxTeams <= 0) {
        structureErrors.maxTeams =
          'Max teams must be greater than 0 for team leagues';
      }
      if (!form.structure.driversPerTeam || form.structure.driversPerTeam <= 0) {
        structureErrors.driversPerTeam =
          'Drivers per team must be greater than 0';
      }
    }
    if (Object.keys(structureErrors).length > 0) {
      errors.structure = structureErrors;
    }
  }

  // Step 4: Schedule (timings)
  if (step === 4) {
    const timingsErrors: NonNullable<WizardErrors['timings']> = {};
    if (!form.timings.qualifyingMinutes || form.timings.qualifyingMinutes <= 0) {
      timingsErrors.qualifyingMinutes =
        'Qualifying duration must be greater than 0 minutes';
    }
    if (!form.timings.mainRaceMinutes || form.timings.mainRaceMinutes <= 0) {
      timingsErrors.mainRaceMinutes =
        'Main race duration must be greater than 0 minutes';
    }
    if (Object.keys(timingsErrors).length > 0) {
      errors.timings = timingsErrors;
    }
  }

  // Step 5: Scoring
  if (step === 5) {
    const scoringErrors: NonNullable<WizardErrors['scoring']> = {};
    if (!form.scoring.patternId && !form.scoring.customScoringEnabled) {
      scoringErrors.patternId =
        'Select a scoring preset or enable custom scoring';
    }
    if (Object.keys(scoringErrors).length > 0) {
      errors.scoring = scoringErrors;
    }
  }

  // Step 6: Stewarding - no validation needed currently (all fields have defaults)
  
  // Step 7: Review - no validation needed, it's just review

  return errors;
}

/**
 * Helper to validate all steps (1-4) and merge errors into a single bag.
 */
export function validateAllLeagueWizardSteps(
  form: LeagueConfigFormModel,
): WizardErrors {
  const aggregate: WizardErrors = {};

  const merge = (next: WizardErrors) => {
    if (next.basics) {
      aggregate.basics = { ...aggregate.basics, ...next.basics };
    }
    if (next.structure) {
      aggregate.structure = { ...aggregate.structure, ...next.structure };
    }
    if (next.timings) {
      aggregate.timings = { ...aggregate.timings, ...next.timings };
    }
    if (next.scoring) {
      aggregate.scoring = { ...aggregate.scoring, ...next.scoring };
    }
    if (next.submit) {
      aggregate.submit = next.submit;
    }
  };

  merge(validateLeagueWizardStep(form, 1));
  merge(validateLeagueWizardStep(form, 2));
  merge(validateLeagueWizardStep(form, 3));
  merge(validateLeagueWizardStep(form, 4));
  merge(validateLeagueWizardStep(form, 5));

  return aggregate;
}

export function hasWizardErrors(errors: WizardErrors): boolean {
  return Object.keys(errors).some((key) => {
    const value = errors[key as keyof WizardErrors];
    if (!value) return false;
    if (typeof value === 'string') return true;
    return Object.keys(value).length > 0;
  });
}

export interface CreateLeagueResult {
  leagueId: string;
  seasonId?: string;
  success: boolean;
}

/**
 * Create a league via API.
 */
export async function createLeagueFromConfig(
  form: LeagueConfigFormModel,
  ownerId: string,
): Promise<CreateLeagueResult> {
  const structure = form.structure;
  let maxDrivers: number;

  if (structure.mode === 'solo') {
    maxDrivers =
      typeof structure.maxDrivers === 'number' && structure.maxDrivers > 0
        ? structure.maxDrivers
        : 0;
  } else {
    const teams =
      typeof structure.maxTeams === 'number' && structure.maxTeams > 0
        ? structure.maxTeams
        : 0;
    const perTeam =
      typeof structure.driversPerTeam === 'number' && structure.driversPerTeam > 0
        ? structure.driversPerTeam
        : 0;
    maxDrivers = teams > 0 && perTeam > 0 ? teams * perTeam : 0;
  }

  const result = await apiClient.leagues.create({
    name: form.basics.name.trim(),
    description: (form.basics.description ?? '').trim(),
    isPublic: form.basics.visibility === 'public',
    maxMembers: maxDrivers,
    ownerId,
  });

  return {
    leagueId: result.leagueId,
    success: result.success,
  };
}

/**
 * Apply scoring preset selection and derive timings, returning a new form model.
 * This mirrors the previous React handler but keeps it in testable, non-UI logic.
 */
export function applyScoringPresetToConfig(
  form: LeagueConfigFormModel,
  patternId: string,
): LeagueConfigFormModel {
  const lowerPresetId = patternId.toLowerCase();
  const timings = form.timings ?? ({} as LeagueConfigFormModel['timings']);
  let updatedTimings: NonNullable<LeagueConfigFormModel['timings']> = {
    ...timings,
  };

  if (lowerPresetId.includes('sprint') || lowerPresetId.includes('double')) {
    updatedTimings = {
      ...updatedTimings,
      practiceMinutes: 15,
      qualifyingMinutes: 20,
      sprintRaceMinutes: 20,
      mainRaceMinutes: 35,
      sessionCount: 2,
    };
  } else if (lowerPresetId.includes('endurance') || lowerPresetId.includes('long')) {
    updatedTimings = {
      ...updatedTimings,
      practiceMinutes: 30,
      qualifyingMinutes: 30,
      mainRaceMinutes: 90,
      sessionCount: 1,
    };
    delete (updatedTimings as { sprintRaceMinutes?: number }).sprintRaceMinutes;
  } else {
    updatedTimings = {
      ...updatedTimings,
      practiceMinutes: 20,
      qualifyingMinutes: 30,
      mainRaceMinutes: 40,
      sessionCount: 1,
    };
    delete (updatedTimings as { sprintRaceMinutes?: number }).sprintRaceMinutes;
  }

  return {
    ...form,
    scoring: {
      ...form.scoring,
      patternId,
      customScoringEnabled: false,
    },
    timings: updatedTimings,
  };
}