import isUrl from 'is-url';
import { withHttps } from 'ufo';
import dayjs from 'dayjs';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';
import { DurationEnum, UserMetadata } from '../../../@types';

// 扩展 dayjs 插件
dayjs.extend(utc);
dayjs.extend(timezone);

const HOUR = 3600;
const MINUTES_30 = 1800;
const MINUTES_10 = 600;
const MINUTES_5 = 300;
const MINUTES_1 = 60;
const SECOND = 1;

export const currentTimezone = dayjs.tz.guess();

// 常用时区列表，作为兼容性 fallback
const COMMON_TIMEZONES = [
  'America/New_York',
  'America/Chicago',
  'America/Denver',
  'America/Los_Angeles',
  'Europe/London',
  'Europe/Paris',
  'Europe/Berlin',
  'Europe/Rome',
  'Asia/Tokyo',
  'Asia/Shanghai',
  'Asia/Hong_Kong',
  'Asia/Singapore',
  'Asia/Seoul',
  'Asia/Kolkata',
  'Australia/Sydney',
  'Australia/Melbourne',
  'Pacific/Auckland',
  'America/Sao_Paulo',
  'America/Mexico_City',
  'Africa/Cairo',
  'UTC',
];

// 获取时区列表的兼容性函数
const getTimezoneList = () => {
  // 优先使用现代 API
  if (typeof Intl !== 'undefined' && Intl.supportedValuesOf) {
    try {
      return Intl.supportedValuesOf('timeZone');
    } catch (error) {
      console.warn('Intl.supportedValuesOf not supported, falling back to common timezones');
    }
  }

  // 尝试使用 Intl.DateTimeFormat 获取时区
  if (typeof Intl !== 'undefined' && Intl.DateTimeFormat) {
    try {
      // 使用 resolvedOptions 检测当前时区是否可用
      const formatter = new Intl.DateTimeFormat('en', { timeZone: 'UTC' });
      if (formatter.resolvedOptions().timeZone) {
        return COMMON_TIMEZONES;
      }
    } catch (error) {
      console.warn('Intl.DateTimeFormat timezone support limited');
    }
  }

  // 最后的 fallback
  return COMMON_TIMEZONES;
};

export const getTimezones = () => {
  const timezones = getTimezoneList();

  const formattedTimezones = timezones
    .map((tz) => {
      try {
        const offset = dayjs.tz(dayjs(), tz).utcOffset() / 60; // 计算 UTC 偏移 (小时)
        const hours = Math.floor(offset);
        const minutes = (offset % 1) * 60;
        const label = `GMT${hours >= 0 ? '+' : ''}${hours}:${minutes === 30 ? '30' : '00'}`;

        return { label, value: tz };
      } catch (error) {
        // 如果时区不支持，跳过
        console.warn(`Timezone ${tz} not supported, skipping`);
        return null;
      }
    })
    .filter((tz): tz is { label: string; value: string } => tz !== null); // 类型守卫

  return formattedTimezones
    .sort((a, b) => {
      const [hoursA, minutesA] = a.label.replace('GMT', '').split(':').map(Number);
      const [hoursB, minutesB] = b.label.replace('GMT', '').split(':').map(Number);
      const totalOffsetA = hoursA * 60 + minutesA; // 统一为分钟数
      const totalOffsetB = hoursB * 60 + minutesB;
      return totalOffsetB - totalOffsetA; // **降序排列**
    })
    .map((tz) => ({
      label: `(${tz.label}) ${tz.value}`,
      value: tz.value,
    }));
};

export const isValidUrl = (url: string) => {
  return isUrl(withHttps(url)); // 补充协议后在进行验证是否是合法的url
};

export const isDuplicateUrl = (url1: string, url2: string) => {
  if (!url1 || !url2) {
    return false;
  }
  if (!isValidUrl(url1) || !isValidUrl(url2)) {
    return false;
  }

  const parsedUrl1 = withHttps(url1.trim());
  const parsedUrl2 = withHttps(url2.trim());
  return parsedUrl1.toLowerCase() === parsedUrl2.toLowerCase();
};

/**
 * 根据 duration 类型，计算出date range
 * @param status
 * @returns
 */
export const getStatusDuration = (status: UserMetadata['status']) => {
  let dateRange: dayjs.Dayjs[] = status?.dateRange?.map((d) => dayjs(d)) ?? [];
  const current = dayjs();
  switch (status?.duration) {
    case DurationEnum.ThirtyMinutes:
      dateRange = [current, current.add(30, 'minutes')];
      break;
    case DurationEnum.OneHour:
      dateRange = [current, current.add(1, 'hour')];
      break;
    case DurationEnum.FourHours:
      dateRange = [current, current.add(4, 'hours')];
      break;
    case DurationEnum.Today:
      dateRange = [current, current.endOf('day')];
      break;
    case DurationEnum.ThisWeek:
      dateRange = [current, current.endOf('week')];
      break;
    case DurationEnum.NoClear:
      dateRange = [current, current];
      break;
    default:
      break;
  }
  return dateRange.map((d) => d.toDate());
};

/**
 * 根据状态的 duration，判断是否在时间范围内
 * @param status
 * @returns
 */
export const isWithinTimeRange = (dateRange: [Date, Date]) => {
  const current = dayjs();
  return current.isAfter(dayjs(dateRange[0])) && current.isBefore(dayjs(dateRange[1]));
};

/**
 * 判断状态持续时间是否为不可清除
 * @param status
 * @returns
 */
export const isNotClear = (status: UserMetadata['status']) => {
  const { duration, dateRange } = status ?? {};
  if (!duration || !dateRange) {
    return false;
  }
  return duration === DurationEnum.NoClear || dayjs(dateRange?.[0]).isSame(dayjs(dateRange?.[1]));
};

/**
 * 获取当前时间距离结束时间还有多久
 */
export const getTimeRemaining = (date: Date) => {
  const now = dayjs();
  const end = dayjs(date);
  const diffSeconds = end.diff(now, 'seconds');

  // 转换为毫秒
  const toMilliseconds = (seconds: number) => seconds * 1000;

  if (diffSeconds >= HOUR) {
    return toMilliseconds(HOUR); // 1小时 = 3600000ms
  }
  if (diffSeconds >= MINUTES_30) {
    return toMilliseconds(MINUTES_30); // 30分钟 = 1800000ms
  }
  if (diffSeconds >= MINUTES_10) {
    return toMilliseconds(MINUTES_10); // 10分钟 = 600000ms
  }
  if (diffSeconds >= MINUTES_5) {
    return toMilliseconds(MINUTES_5); // 5分钟 = 300000ms
  }
  if (diffSeconds >= MINUTES_1) {
    return toMilliseconds(MINUTES_1); // 1分钟 = 60000ms
  }
  if (diffSeconds >= SECOND) {
    return toMilliseconds(SECOND); // 1秒 = 1000ms
  }

  return 0; // 如果时间已过期，返回0
};

// 只支持在 sx 中使用
export const defaultButtonStyle = {
  color: 'text.primary',
  borderColor: 'grey.100',
  backgroundColor: 'background.default',
  '&:hover': {
    borderColor: 'grey.100',
    backgroundColor: 'action.hover',
  },
  py: 0.5,
  borderRadius: 1,
};

export const primaryButtonStyle = {
  color: 'primary.contrastText',
  borderColor: 'primary.main',
  backgroundColor: 'primary.main',
  '&:hover': {
    borderColor: 'primary.main',
    backgroundColor: 'primary.main',
  },
  py: 0.5,
  borderRadius: 1,
};

// 域名关键词到平台标识符的映射表
const DOMAIN_PLATFORM_MAP: Record<string, { domains: string[]; options?: Record<string, any> }> = {
  x: {
    domains: ['twitter.com', 'x.com'],
  },
  facebook: {
    domains: ['facebook.com', 'fb.com'],
    options: { skipDarkInvert: true },
  },
  'linkedin-icon': {
    domains: ['linkedin.com'],
    options: { skipDarkInvert: true },
  },
  'github-icon': {
    domains: ['github.com'],
  },
  'instagram-icon': {
    domains: ['instagram.com'],
  },
  'youtube-icon': {
    domains: ['youtube.com', 'youtu.be'],
    options: { skipDarkInvert: true },
  },
  'tiktok-icon': {
    domains: ['tiktok.com'],
  },
  'reddit-icon': {
    domains: ['reddit.com'],
    options: { skipDarkInvert: true },
  },
  'medium-icon': {
    domains: ['medium.com'],
  },
  'discord-icon': {
    domains: ['discord.com', 'discord.gg'],
    options: { skipDarkInvert: true },
  },
  telegram: {
    domains: ['telegram.org', 't.me'],
    options: { skipDarkInvert: true },
  },
  'whatsapp-monochrome-icon': {
    domains: ['whatsapp.com'],
  },
  producthunt: {
    domains: ['producthunt.com'],
    options: { skipDarkInvert: true },
  },
  ycombinator: {
    domains: ['ycombinator.com', 'news.ycombinator.com'],
    options: { skipDarkInvert: true },
  },
};

export const getLogoByUrl = (url: string): { icon: string; options?: Record<string, any> } | undefined => {
  try {
    // 添加协议（如果没有）
    const fullUrl = withHttps(url);

    // 解析 URL
    const urlObj = new URL(fullUrl);
    const hostname = urlObj.hostname.toLowerCase();

    // 移除 www. 前缀
    const domain = hostname.replace(/^www\./, '');

    // 根据域名返回对应的平台标识符
    for (const [platform, { domains, options }] of Object.entries(DOMAIN_PLATFORM_MAP)) {
      if (domains.some((d) => domain === d || domain.endsWith(`.${d}`))) {
        return {
          icon: `logos:${platform}`,
          options,
        };
      }
    }

    // 对于未匹配的域名，返回空字符串
    return undefined;
  } catch {
    return undefined;
  }
};
