import { extractPalette } from '@/utils/colors';
import api, { API_URL } from '@/services/api';

export type ScoreboardTheme = 'classic' | 'pill' | 'var1' | 'var2' | 'var3' | 'var4';

export type ScoreboardState = {
  homeName: string;
  awayName: string;
  homeLogo?: string;
  awayLogo?: string;
  homeShort?: string;
  awayShort?: string;
  primaryColor?: string; // home color
  secondaryColor?: string; // away color
  homeScore: number;
  awayScore: number;
  halfLength: number; // minutes
  theme: ScoreboardTheme;
  externalMatchId?: string;
  active?: boolean;
  timer?: string; // MM:SS
  running?: boolean;
};

const DEFAULT_STATE: ScoreboardState = {
  homeName: 'DOMÁCÍ',
  awayName: 'HOSTÉ',
  homeLogo: '',
  awayLogo: '',
  homeShort: 'DOM',
  awayShort: 'HOS',
  primaryColor: '#1e3a8a',
  secondaryColor: '#2563eb',
  homeScore: 0,
  awayScore: 0,
  halfLength: 45,
  theme: 'pill',
  externalMatchId: '',
  active: false,
  timer: '00:00',
  running: false,
};

const STORAGE_KEY = 'scoreboard_state_v1';

export async function getScoreboardState(): Promise<ScoreboardState> {
  // Try backend admin singleton first (if authenticated), then fallback to public, then localStorage
  try {
    const res = await api.get('/admin/scoreboard');
    const fromApi = normalizeFromApi(res.data);
    // mirror to localStorage for fast next-load
    localStorage.setItem(STORAGE_KEY, JSON.stringify(fromApi));
    return { ...DEFAULT_STATE, ...fromApi } as ScoreboardState;
  } catch {
    // Not admin or not logged in; try public
    try {
      const base = (API_URL || '').replace(/\/$/, '');
      const res = await fetch(`${base}/scoreboard`, { credentials: 'include' });
      if (res.ok) {
        const data = await res.json();
        const fromApi = normalizeFromApi(data);
        localStorage.setItem(STORAGE_KEY, JSON.stringify(fromApi));
        return { ...DEFAULT_STATE, ...fromApi } as ScoreboardState;
      }
    } catch {}
    // Fallback to localStorage
    try {
      const raw = localStorage.getItem(STORAGE_KEY);
      if (!raw) return DEFAULT_STATE;
      const parsed = JSON.parse(raw);
      return { ...DEFAULT_STATE, ...parsed } as ScoreboardState;
    } catch {
      return DEFAULT_STATE;
    }
  }
}

export async function saveScoreboardState(state: Partial<ScoreboardState>): Promise<ScoreboardState> {
  const current = await getScoreboardState();
  const next = { ...current, ...state } as ScoreboardState;
  localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
  // Attempt to persist to backend if admin
  try {
    await api.put('/admin/scoreboard', toApiPayload(state));
  } catch {
    // ignore if not authorized
  }
  return next;
}

export async function getAdminScoreboard(): Promise<ScoreboardState> {
  const res = await api.get('/admin/scoreboard');
  const fromApi = normalizeFromApi(res.data);
  localStorage.setItem(STORAGE_KEY, JSON.stringify(fromApi));
  return { ...DEFAULT_STATE, ...fromApi } as ScoreboardState;
}

export async function updateAdminScoreboard(patch: Partial<ScoreboardState>): Promise<ScoreboardState> {
  const res = await api.put('/admin/scoreboard', toApiPayload(patch));
  const fromApi = normalizeFromApi(res.data);
  localStorage.setItem(STORAGE_KEY, JSON.stringify(fromApi));
  return { ...DEFAULT_STATE, ...fromApi } as ScoreboardState;
}

export async function getPublicScoreboard(): Promise<ScoreboardState> {
  const base = (API_URL || '').replace(/\/$/, '');
  const res = await fetch(`${base}/scoreboard`, { credentials: 'include' });
  if (!res.ok) throw new Error('Failed to load public scoreboard');
  const data = await res.json();
  const fromApi = normalizeFromApi(data);
  return { ...DEFAULT_STATE, ...fromApi } as ScoreboardState;
}

// Timer controls (admin)
export async function startTimer(): Promise<void> {
  await api.post('/admin/scoreboard/timer/start');
}
export async function pauseTimer(): Promise<void> {
  await api.post('/admin/scoreboard/timer/pause');
}
export async function resetTimer(): Promise<void> {
  await api.post('/admin/scoreboard/timer/reset');
}

// Utilities
export function deriveShort(name?: string): string {
  if (!name) return '---';
  const s = String(name).trim().toUpperCase();
  if (!s) return '---';
  const map: Record<string, string> = {
    'Á':'A','Ä':'A','Å':'A','Â':'A','À':'A',
    'Č':'C','Ć':'C','Ç':'C',
    'Ď':'D',
    'É':'E','Ě':'E','È':'E','Ë':'E','Ê':'E',
    'Í':'I','Ì':'I','Ï':'I','Î':'I',
    'Ň':'N','Ń':'N',
    'Ó':'O','Ö':'O','Ô':'O','Ò':'O',
    'Ř':'R',
    'Š':'S','Ś':'S',
    'Ť':'T',
    'Ú':'U','Ů':'U','Ù':'U','Ü':'U','Û':'U',
    'Ý':'Y',
    'Ž':'Z',
  };
  let out = '';
  for (const ch of s) {
    let c = map[ch] || ch;
    if (c >= 'A' && c <= 'Z') {
      out += c;
      if (out.length === 3) break;
    }
  }
  while (out.length < 3) out += '-';
  return out;
}

export async function derivePrimaryFromLogo(logoUrl?: string): Promise<string | null> {
  if (!logoUrl) return null;
  try {
    const colors = await extractPalette(logoUrl, 5);
    return colors?.[0] || null;
  } catch {
    return null;
  }
}

// Helpers to map API payloads
function normalizeFromApi(d: any): Partial<ScoreboardState> {
  if (!d) return {};
  return {
    homeName: d.homeName || d.home_name || d.HomeName || '',
    awayName: d.awayName || d.away_name || d.AwayName || '',
    homeLogo: d.homeLogo || d.home_logo || d.home_logo_url || d.HomeLogoURL || '',
    awayLogo: d.awayLogo || d.away_logo || d.away_logo_url || d.AwayLogoURL || '',
    homeShort: d.homeShort || d.home_short || d.HomeShort || '',
    awayShort: d.awayShort || d.away_short || d.AwayShort || '',
    primaryColor: d.primaryColor || d.primary_color || d.PrimaryColor || undefined,
    secondaryColor: d.secondaryColor || d.secondary_color || d.SecondaryColor || undefined,
    homeScore: typeof d.homeScore === 'number' ? d.homeScore : (typeof d.home_score === 'number' ? d.home_score : 0),
    awayScore: typeof d.awayScore === 'number' ? d.awayScore : (typeof d.away_score === 'number' ? d.away_score : 0),
    halfLength: typeof d.halfLength === 'number' ? d.halfLength : (typeof d.half_length === 'number' ? d.half_length : 45),
    theme: (d.theme || 'pill') as any,
    externalMatchId: d.externalMatchId || d.external_match_id || d.ExternalMatchID || '',
    active: typeof d.active === 'boolean' ? d.active : undefined,
    timer: d.timer || d.Timer || '00:00',
    running: typeof d.running === 'boolean' ? d.running : undefined,
  };
}

function toApiPayload(p: Partial<ScoreboardState>) {
  const out: any = {};
  if (p.homeName !== undefined) out.homeName = p.homeName;
  if (p.awayName !== undefined) out.awayName = p.awayName;
  if (p.homeLogo !== undefined) out.homeLogo = p.homeLogo;
  if (p.awayLogo !== undefined) out.awayLogo = p.awayLogo;
  if (p.homeShort !== undefined) out.homeShort = p.homeShort;
  if (p.awayShort !== undefined) out.awayShort = p.awayShort;
  if (p.primaryColor !== undefined) out.primaryColor = p.primaryColor;
  if (p.secondaryColor !== undefined) out.secondaryColor = p.secondaryColor;
  if (p.homeScore !== undefined) out.homeScore = p.homeScore;
  if (p.awayScore !== undefined) out.awayScore = p.awayScore;
  if (p.halfLength !== undefined) out.halfLength = p.halfLength;
  if (p.theme !== undefined) out.theme = p.theme;
  if (p.externalMatchId !== undefined) out.externalMatchId = p.externalMatchId;
  if (p.active !== undefined) out.active = p.active;
  if (p.timer !== undefined) out.timer = p.timer;
  return out;
}
