import { assetUrl } from '../utils/url';

export interface RelatedClub {
  id: string;
  name: string;
  logo_url?: string;
  competition?: string;
  last_played_iso?: string;
  matches_played?: number;
}

const normalize = (value: string) =>
  String(value || '')
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .replace(/\s+/g, ' ')
    .trim()
    .toLowerCase();

const resolveBackendUrl = (path: string): string => {
  try {
    if (/^https?:\/\//i.test(path)) return path;
    if (path.startsWith('/cache') || path.startsWith('/uploads') || path.startsWith('/api/')) {
      const base = process.env.REACT_APP_API_BASE_URL || process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
      const origin = new URL(base).origin;
      return new URL(path, origin).toString();
    }
    return path;
  } catch {
    return path;
  }
};

const fetchJSON = async <T>(path: string): Promise<T | null> => {
  try {
    const res = await fetch(resolveBackendUrl(path), { cache: 'no-cache' });
    if (!res.ok) return null;
    return (await res.json()) as T;
  } catch {
    return null;
  }
};

const parseDateTime = (dt?: string): Date | null => {
  if (!dt) return null;
  const [datePart, timePart = '00:00'] = String(dt).split(' ');
  const [day, month, year] = (datePart || '').split('.');
  if (!day || !month || !year) return null;
  const iso = `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}T${timePart.slice(0, 5)}:00`;
  const d = new Date(iso);
  return Number.isNaN(d.getTime()) ? null : d;
};

let cachePromise: Promise<RelatedClub[]> | null = null;

const buildRelatedClubs = (clubInfo: any): RelatedClub[] => {
  if (!clubInfo) return [];
  const ourNameNorm = normalize(clubInfo.name || '');
  const competitions = Array.isArray(clubInfo.competitions) ? clubInfo.competitions : [];
  const map = new Map<string, RelatedClub & { lastPlayedDate?: Date }>();

  const considerTeam = (team: {
    name?: string;
    id?: string;
    logo?: string;
    competition?: string;
    occurredAt?: Date | null;
  }) => {
    const teamName = team.name?.trim();
    if (!teamName) return;
    const normName = normalize(teamName);
    if (!normName || normName === ourNameNorm) return;

    const existing = map.get(normName);
    const matchesPlayed = (existing?.matches_played ?? 0) + 1;
    const lastPlayedDate = team.occurredAt && (!existing?.lastPlayedDate || team.occurredAt > existing.lastPlayedDate)
      ? team.occurredAt
      : existing?.lastPlayedDate;
    const logoUrl = team.logo || existing?.logo_url;
    const competition = team.competition || existing?.competition;

    map.set(normName, {
      id: team.id || existing?.id || normName,
      name: teamName,
      logo_url: logoUrl ? assetUrl(logoUrl) || logoUrl : existing?.logo_url,
      competition,
      matches_played: matchesPlayed,
      last_played_iso: lastPlayedDate ? lastPlayedDate.toISOString() : existing?.last_played_iso,
      lastPlayedDate,
    });
  };

  competitions.forEach((comp: any) => {
    const matches = Array.isArray(comp?.matches) ? comp.matches : [];
    matches.forEach((match: any) => {
      const occurredAt = parseDateTime(match?.date_time);
      considerTeam({
        name: match?.home,
        id: match?.home_id || match?.homeId,
        logo: match?.home_logo_url,
        competition: comp?.name,
        occurredAt,
      });
      considerTeam({
        name: match?.away,
        id: match?.away_id || match?.awayId,
        logo: match?.away_logo_url,
        competition: comp?.name,
        occurredAt,
      });
    });
  });

  return Array.from(map.values())
    .map(({ lastPlayedDate, ...rest }) => rest)
    .sort((a, b) => {
      const ad = a.last_played_iso ? new Date(a.last_played_iso).getTime() : 0;
      const bd = b.last_played_iso ? new Date(b.last_played_iso).getTime() : 0;
      return bd - ad;
    });
};

const fetchRelatedClubs = async (): Promise<RelatedClub[]> => {
  const clubInfo = await fetchJSON<any>('/cache/prefetch/facr_club_info.json');
  if (!clubInfo) return [];
  return buildRelatedClubs(clubInfo);
};

export const getRelatedClubs = async (): Promise<RelatedClub[]> => {
  if (!cachePromise) {
    cachePromise = fetchRelatedClubs().catch(() => []);
  }
  return cachePromise;
};
