import type { SupabaseClient } from '@supabase/supabase-js';

const FORTY_EIGHT_HOURS = 48 * 60 * 60 * 1000; // 48 hours in milliseconds

export interface LapRecordInput {
  round: number;
  riderClass: '250SX' | '450SX';
  lapTime: string;
  riderName: string;
  riderNumber: string;
  // Supercross and Pro Motocross each number their own rounds 1-N independently (e.g. SX
  // round 8 = Daytona, MX round 8 = Washougal), so the series must be part of the record's
  // identity or the two would collide on (event_round, class) alone.
  series: 'sx' | 'mx';
}

export interface LapRecordResult {
  updated: boolean;
  record: {
    lapTime: string;
    riderName: string;
    riderNumber: string;
    setAt: string; // ISO string
    createdAt: string; // ISO string
  };
}

/**
 * Saves a lap time as the event record for a round/class if it beats the existing one.
 * Handles the 48-hour record expiry (an expired record is deleted and replaced fresh).
 * Shared by the client-driven POST /api/event-records route and the server-side
 * /api/track-fastest-laps poller so both write identical data.
 */
export async function saveLapRecordIfFaster(
  supabase: SupabaseClient,
  { round, riderClass, lapTime, riderName, riderNumber, series }: LapRecordInput
): Promise<LapRecordResult> {
  // Check if a record exists for this round, class, and series
  let { data: existingRecord, error: fetchError } = await supabase
    .from('event_lap_records')
    .select('*')
    .eq('event_round', round)
    .eq('class', riderClass)
    .eq('series', series)
    .single();

  if (fetchError && fetchError.code !== 'PGRST116') {
    // PGRST116 is "not found" which is okay
    console.error('[LapRecords] Error fetching existing record:', fetchError);
  }

  // Check if record is expired
  if (existingRecord) {
    const now = new Date().getTime();
    const createdAt = new Date(existingRecord.created_at).getTime();
    const age = now - createdAt;

    if (age > FORTY_EIGHT_HOURS) {
      console.log('[LapRecords] Deleting expired record');
      const { error: deleteError } = await supabase
        .from('event_lap_records')
        .delete()
        .eq('event_round', round)
        .eq('class', riderClass)
        .eq('series', series);

      if (deleteError) {
        console.error('[LapRecords] Error deleting expired record:', deleteError);
      } else {
        // Clear existingRecord so a fresh record with new created_at will be created
        existingRecord = null;
      }
    } else {
      // Check if new lap is faster
      const currentLapTime = parseFloat(lapTime);
      const existingLapTime = parseFloat(existingRecord.lap_time);

      if (currentLapTime >= existingLapTime) {
        // Not faster, return existing record
        return {
          updated: false,
          record: {
            lapTime: existingRecord.lap_time,
            riderName: existingRecord.rider_name,
            riderNumber: existingRecord.rider_number,
            setAt: existingRecord.updated_at,
            createdAt: existingRecord.created_at,
          },
        };
      }
    }
  }

  // Delete any leftover row first when starting fresh, so timestamps reset cleanly
  if (!existingRecord) {
    const { error: cleanupError } = await supabase
      .from('event_lap_records')
      .delete()
      .eq('event_round', round)
      .eq('class', riderClass)
      .eq('series', series);

    if (cleanupError) {
      console.error('[LapRecords] Cleanup delete error:', cleanupError);
    }
  }

  // Insert or update the record
  const recordData: any = {
    event_round: round,
    class: riderClass,
    series,
    lap_time: lapTime,
    rider_name: riderName,
    rider_number: riderNumber,
  };

  // Only preserve created_at if we have a valid existing record
  if (existingRecord) {
    recordData.created_at = existingRecord.created_at;
  }

  const { data, error } = await supabase
    .from('event_lap_records')
    .upsert(recordData, {
      onConflict: 'event_round,class,series'
    })
    .select()
    .single();

  if (error) {
    console.error('[LapRecords] Error updating lap record:', error);
    throw error;
  }

  return {
    updated: true,
    record: {
      lapTime: data.lap_time,
      riderName: data.rider_name,
      riderNumber: data.rider_number,
      setAt: data.updated_at,
      createdAt: data.created_at || new Date().toISOString(),
    },
  };
}
