import { toZonedTime, fromZonedTime } from 'date-fns-tz';

export const TENANT_DEFAULT_TIMEZONE = 'America/Los_Angeles';

export const COMMON_TIMEZONES = [
  { value: 'UTC', label: 'UTC' },
  { value: 'Asia/Shanghai', label: 'Asia/Shanghai' },
  { value: 'Asia/Tokyo', label: 'Asia/Tokyo' },
  { value: 'Asia/Seoul', label: 'Asia/Seoul' },
  { value: 'Asia/Singapore', label: 'Asia/Singapore' },
  { value: 'Asia/Hong_Kong', label: 'Asia/Hong_Kong' },
  { value: 'Asia/Taipei', label: 'Asia/Taipei' },
  { value: 'America/New_York', label: 'America/New_York' },
  { value: 'America/Los_Angeles', label: 'America/Los_Angeles' },
  { value: 'America/Chicago', label: 'America/Chicago' },
  { value: 'Europe/London', label: 'Europe/London' },
  { value: 'Europe/Paris', label: 'Europe/Paris' },
  { value: 'Europe/Berlin', label: 'Europe/Berlin' },
  { value: 'Australia/Sydney', label: 'Australia/Sydney' },
  { value: 'Australia/Melbourne', label: 'Australia/Melbourne' },
];

export function convertToUTC(localDateTime: string, timezone: string): Date {
  try {
    return fromZonedTime(localDateTime, timezone);
  } catch (error) {
    console.error('Error converting to UTC:', error);
    return new Date(localDateTime);
  }
}

export function convertFromUTC(utcDate: Date, timezone: string): string {
  try {
    const zoned = toZonedTime(utcDate, timezone);
    const year = zoned.getFullYear();
    const month = String(zoned.getMonth() + 1).padStart(2, '0');
    const day = String(zoned.getDate()).padStart(2, '0');
    const hours = String(zoned.getHours()).padStart(2, '0');
    const minutes = String(zoned.getMinutes()).padStart(2, '0');
    return `${year}-${month}-${day}T${hours}:${minutes}`;
  } catch (error) {
    console.error('Error converting from UTC:', error);
    return utcDate.toISOString().slice(0, 16);
  }
}

export function formatTimeRange(startTime: Date, endTime: Date, timezone: string): string {
  try {
    const startText = formatInstant(startTime, timezone);
    const endText = formatInstant(endTime, timezone);
    return `${startText} - ${endText}`;
  } catch (error) {
    console.error('Error formatting time range:', error);
    return `${startTime.toLocaleString()} - ${endTime.toLocaleString()}`;
  }
}

export function formatInstant(utcDate: Date, timezone: string): string {
  try {
    const formatter = new Intl.DateTimeFormat('en-CA', {
      timeZone: timezone,
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      hour12: false,
    });

    const parts = formatter.formatToParts(utcDate);
    const year = parts.find((part) => part.type === 'year')?.value || '';
    const month = parts.find((part) => part.type === 'month')?.value || '';
    const day = parts.find((part) => part.type === 'day')?.value || '';
    const hour = parts.find((part) => part.type === 'hour')?.value || '';
    const minute = parts.find((part) => part.type === 'minute')?.value || '';

    return `${year}-${month}-${day} ${hour}:${minute}`;
  } catch (error) {
    console.error('Error formatting instant:', error);
    return utcDate.toISOString();
  }
}

function formatTimezoneAbbreviation(utcDate: Date, timezone: string): string {
  try {
    const formatter = new Intl.DateTimeFormat('en-US', {
      timeZone: timezone,
      timeZoneName: 'short',
    });
    const parts = formatter.formatToParts(utcDate);
    return parts.find((part) => part.type === 'timeZoneName')?.value || timezone;
  } catch (error) {
    console.error('Error formatting timezone abbreviation:', error);
    return timezone;
  }
}

export function formatInstantWithTimezone(utcDate: Date, timezone: string): string {
  const tzShort = formatTimezoneAbbreviation(utcDate, timezone);
  return `${formatInstant(utcDate, timezone)} ${tzShort}`;
}

export function formatTimeRangeWithTimezone(startTime: Date, endTime: Date, timezone: string): string {
  const tzShort = formatTimezoneAbbreviation(startTime, timezone);
  return `${formatTimeRange(startTime, endTime, timezone)} ${tzShort}`;
}

export function formatMeetingInstantDisplay(
  utcDate: Date,
  meetingTimezone: string,
  displayTimezone: string,
): { primary: string; secondary: string | null } {
  const normalizedMeetingTimezone = meetingTimezone || TENANT_DEFAULT_TIMEZONE;
  const normalizedDisplayTimezone = displayTimezone || TENANT_DEFAULT_TIMEZONE;
  const primary = formatInstantWithTimezone(utcDate, normalizedMeetingTimezone);
  if (normalizedDisplayTimezone === normalizedMeetingTimezone) {
    return { primary, secondary: null };
  }
  return {
    primary,
    secondary: formatInstantWithTimezone(utcDate, normalizedDisplayTimezone),
  };
}

export function formatMeetingRangeDisplay(
  startTime: Date,
  endTime: Date,
  meetingTimezone: string,
  displayTimezone: string,
): { primary: string; secondary: string | null } {
  const normalizedMeetingTimezone = meetingTimezone || TENANT_DEFAULT_TIMEZONE;
  const normalizedDisplayTimezone = displayTimezone || TENANT_DEFAULT_TIMEZONE;
  const primary = formatTimeRangeWithTimezone(startTime, endTime, normalizedMeetingTimezone);
  if (normalizedDisplayTimezone === normalizedMeetingTimezone) {
    return { primary, secondary: null };
  }
  return {
    primary,
    secondary: formatTimeRangeWithTimezone(startTime, endTime, normalizedDisplayTimezone),
  };
}

export function getUserTimezone(): string {
  try {
    return Intl.DateTimeFormat().resolvedOptions().timeZone;
  } catch (error) {
    console.error('Error getting user timezone:', error);
    return TENANT_DEFAULT_TIMEZONE;
  }
}
