import { format } from 'date-fns';
import { enUS, hu } from 'date-fns/locale';

import { Event, EventInstitutionField, InstitutionAddress } from '@/types/Events';

// Build location string from institution field with organizational unit and venue
export const getInstitutionLocationString = (
  institutionField: EventInstitutionField
): string | null => {
  if (!institutionField) return null;

  const { intezmeny, szervezetiEgyseg, helyszin } = institutionField;
  const parts: string[] = [];

  // Add institution name
  if (intezmeny?.nev) {
    parts.push(intezmeny.nev);
  }

  // Add organizational units (egyseg1, egyseg2, egyseg3) if exist
  if (szervezetiEgyseg?.egyseg1) {
    parts.push(szervezetiEgyseg.egyseg1);
  }
  if (szervezetiEgyseg?.egyseg2) {
    parts.push(szervezetiEgyseg.egyseg2);
  }
  if (szervezetiEgyseg?.egyseg3) {
    parts.push(szervezetiEgyseg.egyseg3);
  }

  // Add venue (helyszin) if exists
  if (helyszin) {
    parts.push(helyszin);
  }

  // Determine which address to use: organizational unit's or institution's
  const address = szervezetiEgyseg?.cim || intezmeny?.intezmenyCime;

  if (address) {
    // Clean zip code: remove .0 suffix if present
    const cleanZip = address.zip ? address.zip.replace(/\.0$/, '') : null;

    // Add zip and city together (no comma between them)
    const locationPart = [cleanZip, address.city].filter(Boolean).join(' ');
    if (locationPart) {
      parts.push(locationPart);
    }

    // Add address
    if (address.address1) {
      parts.push(address.address1);
    }
  }

  return parts.length > 0 ? parts.join(', ') : null;
};

// Get coordinates from institution or event
export const getInstitutionCoordinates = (
  institutionAddress: InstitutionAddress
): string | null => {
  if (institutionAddress?.koordinatak) {
    return institutionAddress.koordinatak;
  }
  return null;
};

// Convert UTC date string to Budapest timezone
export const toBudapestDate = (utcString: string): Date => {
  const utcDate = new Date(utcString);
  const budapestString = utcDate.toLocaleString('en-US', {
    timeZone: 'Europe/Budapest',
  });
  return new Date(budapestString);
};

export const getEventStartDateString = (
  event: Event,
  isLongFormat: boolean = false,
  locale: string = 'hu'
): string => {
  const startDate = toBudapestDate(event.kezdete);
  if (isNaN(startDate.getTime())) return '';

  const includeTime = !event.kezdeteDatum;
  const dateLocale = locale === 'en' ? enUS : hu;

  if (isLongFormat) {
    // Long format: "November 5, 2025 (Tuesday), 18:00" or "November 5, 2025 (Tuesday)"
    const formatString =
      locale === 'en'
        ? includeTime
          ? 'MMMM d, yyyy (EEEE), HH:mm'
          : 'MMMM d, yyyy (EEEE)'
        : includeTime
          ? 'yyyy. MMMM d. (EEEE), HH:mm'
          : 'yyyy. MMMM d. (EEEE)';
    return format(startDate, formatString, { locale: dateLocale });
  } else {
    // Short format: "2025.11.5." or "11/05/2025"
    const formatString = locale === 'en' ? 'MM/dd/yyyy' : 'yyyy.MM.dd.';
    return format(startDate, formatString, { locale: dateLocale });
  }
};

const getEventEndDateString = (
  event: Event,
  isLongFormat: boolean = false,
  locale: string = 'hu'
): string | null => {
  if (!event.vege) return null;
  const endDate = toBudapestDate(event.vege);
  if (isNaN(endDate.getTime())) return null;

  const includeTime = !event.vegeDatum;
  const dateLocale = locale === 'en' ? enUS : hu;

  if (isLongFormat) {
    // Long format: "November 5, 2025 (Tuesday), 18:00" or "November 5, 2025 (Tuesday)"
    const formatString =
      locale === 'en'
        ? includeTime
          ? 'MMMM d, yyyy (EEEE), HH:mm'
          : 'MMMM d, yyyy (EEEE)'
        : includeTime
          ? 'yyyy. MMMM d. (EEEE), HH:mm'
          : 'yyyy. MMMM d. (EEEE)';
    return format(endDate, formatString, { locale: dateLocale });
  } else {
    // Short format: "2025.11.5." or "11/05/2025"
    const formatString = locale === 'en' ? 'MM/dd/yyyy' : 'yyyy.MM.dd.';
    return format(endDate, formatString, { locale: dateLocale });
  }
};

// Create string interval for event
export const getEventTimeIntervalString = (
  event: Event,
  isLongFormat: boolean = false,
  locale: string = 'hu'
): string => {
  const startStr = getEventStartDateString(event, isLongFormat, locale);
  const endStr = getEventEndDateString(event, isLongFormat, locale);

  if (endStr) {
    return `${startStr} – ${endStr}`;
  }
  return startStr;
};

export const getEventCultTypeLabel = (event: Event): string => {
  return event.kulturalisAltipus?.[0]?.nev || event.kulturalisTipus?.[0]?.nev || '';
};
