import api, { API_URL } from './api';

export type AdminMatch = Record<string, any> & {
  match_id?: string;
  id?: string;
  home?: string;
  away?: string;
  venue?: string;
  date_time?: string;
  home_logo_url?: string;
  away_logo_url?: string;
};

export async function fetchAdminMatches(): Promise<AdminMatch[]> {
  const res = await api.get('/admin/matches');
  return Array.isArray(res.data) ? res.data : res.data?.data ?? [];
}

export type MatchOverrideInput = {
  home_name_override?: string | null;
  away_name_override?: string | null;
  venue_override?: string | null;
  date_time_override?: string | null; // ISO string
  home_logo_url?: string | null;
  away_logo_url?: string | null;
  notes?: string | null;
};

export async function putMatchOverride(externalMatchId: string, payload: MatchOverrideInput) {
  // Normalize date_time_override to RFC3339 if present
  const body: any = { ...payload };
  if (typeof body.date_time_override === 'string' && body.date_time_override.trim() !== '') {
    const d = new Date(body.date_time_override);
    if (!isNaN(d.getTime())) {
      body.date_time_override = d.toISOString();
    }
  }
  return (await api.put(`/admin/match-overrides/${encodeURIComponent(externalMatchId)}`, body)).data;
}

export async function patchMatchOverride(externalMatchId: string, payload: Partial<MatchOverrideInput>) {
  const body: any = { ...payload };
  if (typeof body.date_time_override === 'string' && body.date_time_override.trim() !== '') {
    const d = new Date(body.date_time_override);
    if (!isNaN(d.getTime())) {
      body.date_time_override = d.toISOString();
    }
  }
  return (await api.patch(`/admin/match-overrides/${encodeURIComponent(externalMatchId)}`, body)).data;
}

export async function putTeamLogoOverride(externalTeamId: string, teamName: string, logoUrl: string) {
  return (await api.put(`/admin/team-logo-overrides/${encodeURIComponent(externalTeamId)}`, { team_name: teamName, logo_url: logoUrl })).data;
}

interface UploadLogoOptions {
  filename?: string;
  clubName?: string;
  clubType?: 'football' | 'futsal';
}

/**
 * Upload logo to logoapi.sportcreative.eu
 * This is the primary logo storage for the application
 */
export async function uploadToLogaSportcreative(
  clubId: string,
  logoFile: File | Blob,
  options: UploadLogoOptions = {}
): Promise<{ success: boolean; url?: string; error?: string }> {
  try {
    const formData = new FormData();
    const filename = options.filename || (logoFile instanceof File ? logoFile.name : 'logo.png');
    
    // Required fields
    formData.append('file', logoFile, filename);
    formData.append('club_name', options.clubName || 'Neznámý klub');
    
    // Optional field - only club_type is needed
    if (options.clubType) {
      formData.append('club_type', options.clubType);
    }

    const response = await fetch(`https://logoapi.sportcreative.eu/logos/${clubId}`, {
      method: 'POST',
      body: formData,
    });

    const responseData = await response.json().catch(() => ({}));

    if (!response.ok) {
      return { 
        success: false, 
        error: responseData.error || `HTTP ${response.status}: ${response.statusText}`
      };
    }

    // Construct the logo URL from the response
    const logoUrl = responseData.logo_url || 
                   responseData.logo_url_svg || 
                   responseData.logo_url_png ||
                   `https://logoapi.sportcreative.eu/logos/${clubId}/logo.svg`;

    return { 
      success: true, 
      url: logoUrl
    };
  } catch (error: any) {
    console.error('Error uploading logo:', error);
    return { 
      success: false, 
      error: error?.message || 'Nepodařilo se nahrát logo. Zkuste to prosím znovu.'
    };
  }
}

/**
 * Upload logo to sportlogos.tdvorak.dev external API
 * This runs in parallel with the local save to provide logo backup/sharing
 */
export async function uploadToSportLogosAPI(
  clubId: string,
  clubName: string,
  logoFile: File | Blob,
  options?: {
    club_type?: 'football' | 'futsal';
    club_website?: string;
    club_city?: string;
  }
): Promise<{ success: boolean; error?: string }> {
  try {
    const formData = new FormData();
    formData.append('file', logoFile, logoFile instanceof File ? logoFile.name : 'logo.png');
    formData.append('club_name', clubName);
    
    if (options?.club_type) {
      formData.append('club_type', options.club_type);
    }
    if (options?.club_website) {
      formData.append('club_website', options.club_website);
    }
    if (options?.club_city) {
      formData.append('club_city', options.club_city);
    }

    const response = await fetch(`https://sportlogos.tdvorak.dev/logos/${clubId}`, {
      method: 'POST',
      body: formData,
    });

    if (!response.ok) {
      const errorData = await response.json().catch(() => ({}));
      return { 
        success: false, 
        error: (errorData as any)?.error || `HTTP ${response.status}: ${response.statusText}` 
      };
    }

    const result = await response.json();
    return { success: true };
  } catch (error: any) {
    return { 
      success: false, 
      error: error?.message || 'Network error uploading to sportlogos.tdvorak.dev' 
    };
  }
}

/**
 * Helper to fetch logo file from URL (for re-uploading already uploaded logos)
 */
export async function fetchLogoAsBlob(logoUrl: string): Promise<Blob | null> {
  try {
    // Resolve relative URLs against the API origin
    let fullUrl = logoUrl;
    if (logoUrl.startsWith('/')) {
      const apiOrigin = new URL(API_URL).origin;
      fullUrl = `${apiOrigin}${logoUrl}`;
    }

    const response = await fetch(fullUrl);
    if (!response.ok) return null;
    
    return await response.blob();
  } catch (error) {
    console.error('Failed to fetch logo as blob:', error);
    return null;
  }
}

/**
 * Fetch logo metadata from logoapi.sportcreative.eu
 * Returns logo URL if available, null if not found
 */
export type SportLogoMetadata = {
  id: string;
  club_name: string;
  club_type?: string;
  club_website?: string;
  has_svg?: boolean;
  has_png?: boolean;
  primary_format?: string;
  logo_url?: string;
  logo_url_svg?: string;
  logo_url_png?: string;
  file_size_svg?: number;
  file_size_png?: number;
  created_at?: string;
  updated_at?: string;
};

export async function fetchLogoFromSportLogosAPI(clubId: string): Promise<string | null> {
  try {
    const response = await fetch(`https://logoapi.sportcreative.eu/logos/${clubId}/json`, {
      method: 'GET',
      headers: {
        'Accept': 'application/json',
      },
    });

    if (!response.ok) {
      return null; // Logo not found or error
    }

    const data: SportLogoMetadata = await response.json();
    
    // Prefer SVG, fallback to PNG, fallback to generic logo_url
    return data.logo_url_svg || data.logo_url_png || data.logo_url || null;
  } catch (error) {
    console.error('Failed to fetch logo from logoapi.sportcreative.eu:', error);
    return null;
  }
}

/**
 * Fetch logo with priority: logoapi.sportcreative.eu -> local overrides -> FACR original
 */
export async function fetchLogoWithFallback(
  clubId: string | null | undefined,
  teamName: string,
  facrLogoUrl?: string,
  localOverrides?: Record<string, string>
): Promise<string> {
  const defaultLogo = '/dist/img/logo-club-empty.svg';
  
  // Try logoapi.sportcreative.eu first if we have a club ID
  if (clubId) {
    const sportLogo = await fetchLogoFromSportLogosAPI(clubId);
    if (sportLogo) {
      return sportLogo;
    }
  }
  
  // Try local overrides
  if (localOverrides && teamName) {
    const overrideLogo = localOverrides[teamName];
    if (overrideLogo) {
      return overrideLogo;
    }
  }
  
  // Fallback to FACR original
  if (facrLogoUrl) {
    return facrLogoUrl;
  }
  
  // Final fallback to default empty logo
  return defaultLogo;
}

/**
 * Batch fetch logos from sportlogos.tdvorak.dev for multiple teams
 * Returns a map of team_id -> logo URL
 * This is more efficient than fetching one by one
 */
export async function batchFetchLogosFromSportLogosAPI(
  clubIds: string[]
): Promise<Record<string, string>> {
  const logoMap: Record<string, string> = {};
  
  // Fetch in parallel with a limit to avoid overwhelming the server
  const BATCH_SIZE = 10;
  for (let i = 0; i < clubIds.length; i += BATCH_SIZE) {
    const batch = clubIds.slice(i, i + BATCH_SIZE);
    const promises = batch.map(async (clubId) => {
      const logo = await fetchLogoFromSportLogosAPI(clubId);
      if (logo) {
        logoMap[clubId] = logo;
      }
    });
    await Promise.all(promises);
  }
  
  return logoMap;
}

export async function uploadImage(file: File): Promise<{ url: string }> {
  const fd = new FormData();
  fd.append('file', file);
  const res = await api.post('/upload', fd, {
    headers: { 'Content-Type': 'multipart/form-data' },
  });
  const data = res.data;
  let url = data?.url || '';
  try {
    const parsed = new URL(url, window.location.origin);
    const appOrigin = window.location.origin;
    const apiOrigin = new URL(API_URL).origin;
    if (parsed.origin === appOrigin || parsed.origin === apiOrigin) {
      // store backend-relative path so DB records are consistent
      url = parsed.pathname + parsed.search + parsed.hash;
    }
  } catch (e) {
    // ignore and return whatever the backend provided
  }
  return { ...(data || {}), url };
}

export type ClubSearchResult = { id: string; name: string; logo_url?: string };
export async function searchClubs(query: string): Promise<ClubSearchResult[]> {
  if (!query || query.trim().length < 2) return [];
  const res = await api.get(`/facr/club/search`, { params: { q: query } });
  const raw = res.data?.results ?? res.data ?? [];
  // Normalize backend payload (which uses club_id) to { id, name, logo_url }
  const mapped = Array.isArray(raw)
    ? raw.map((r: any) => ({
        id: r?.id ?? r?.club_id ?? r?.ClubID ?? '',
        name: r?.name ?? r?.Name ?? '',
        logo_url: r?.logo_url ?? r?.LogoURL ?? undefined,
      }))
    : [];
  return mapped.filter((x: ClubSearchResult) => x.id && x.name);
}

// Public team-logo overrides map to apply on cache-fed widgets/pages.
// Shape: { by_name: { [teamName: string]: string /* logo URL */ } }
export type TeamLogoOverrides = { by_name?: Record<string, string> };
export async function fetchTeamLogoOverrides(): Promise<TeamLogoOverrides> {
  try {
    // Try public endpoint first (recommended for widgets)
    // Add cache-busting param to avoid 120s public cache when user just saved changes
    const res = await api.get('/public/team-logo-overrides', { params: { t: Date.now() } });
    return res.data ?? {};
  } catch {
    // Fallback: try admin (requires auth); if that fails, return empty
    try {
      const res2 = await api.get('/admin/team-logo-overrides', { params: { t: Date.now() } });
      const data = res2.data;
      // If admin returns an array of overrides, normalize to { by_name }
      if (Array.isArray(data)) {
        const byName: Record<string, string> = {};
        for (const it of data) {
          const name = it?.team_name || it?.TeamName;
          const logo = it?.logo_url || it?.LogoURL;
          if (name && logo) byName[String(name)] = String(logo);
        }
        return { by_name: byName };
      }
      // If already in desired shape, return as-is
      if (data && typeof data === 'object' && data.by_name) return data;
      return {};
    } catch {
      return {};
    }
  }
}
