/*
  author: Yagnik Poshiya
  organization: Webbrains Technologies Private Limited
*/

export const WIDGET_LAUNCHER_ICON_MODES = ['lucide', 'custom_url'] as const;
export type WidgetLauncherIconMode = (typeof WIDGET_LAUNCHER_ICON_MODES)[number];

export const WIDGET_LUCIDE_ICON_KEYS = [
  'user-round',
  'message-circle',
  'bot',
  'sparkles',
  'circle-help',
  'message-square',
  'send',
  'headset',
  'life-buoy',
  'badge-help',
  'info',
  'mail',
  'phone',
  'megaphone',
  'bell',
  'rocket',
  'shield-check',
  'user',
  'at-sign',
  'book-open',
] as const;
export type WidgetLucideIconKey = (typeof WIDGET_LUCIDE_ICON_KEYS)[number];

export const WIDGET_LUCIDE_ICON_OPTIONS: Array<{ value: WidgetLucideIconKey; label: string }> = [
  { value: 'user-round', label: 'User Round' },
  { value: 'message-circle', label: 'Message Circle' },
  { value: 'bot', label: 'Bot' },
  { value: 'sparkles', label: 'Sparkles' },
  { value: 'circle-help', label: 'Circle Help' },
  { value: 'message-square', label: 'Message Square' },
  { value: 'send', label: 'Send' },
  { value: 'headset', label: 'Headset' },
  { value: 'life-buoy', label: 'Life Buoy' },
  { value: 'badge-help', label: 'Badge Help' },
  { value: 'info', label: 'Info' },
  { value: 'mail', label: 'Mail' },
  { value: 'phone', label: 'Phone' },
  { value: 'megaphone', label: 'Megaphone' },
  { value: 'bell', label: 'Bell' },
  { value: 'rocket', label: 'Rocket' },
  { value: 'shield-check', label: 'Shield Check' },
  { value: 'user', label: 'User' },
  { value: 'at-sign', label: 'At Sign' },
  { value: 'book-open', label: 'Book Open' },
];

export type WidgetLauncherIconConfig = {
  mode: WidgetLauncherIconMode;
  lucideIcon: WidgetLucideIconKey;
  customIconUrl: string | null;
};

export const DEFAULT_WIDGET_LAUNCHER_ICON: WidgetLauncherIconConfig = {
  mode: 'lucide',
  lucideIcon: 'user-round',
  customIconUrl: null,
};

const MAX_CUSTOM_ICON_URL_LENGTH = 512;

/** Maximum file size for uploaded custom widget icons (100 KB). */
export const MAX_WIDGET_ICON_FILE_SIZE_BYTES = 100 * 1024;

/** Maximum file size for animated avatar launchers — GIF/MP4 (1 MB). */
export const MAX_WIDGET_AVATAR_FILE_SIZE_BYTES = 1024 * 1024;

/**
 * Extensions rendered as a full "avatar" launcher: the round button chrome is
 * removed and the animated asset itself becomes the launcher.
 */
const WIDGET_AVATAR_EXTENSIONS = new Set(['gif', 'mp4']);

const ALLOWED_WIDGET_ICON_MIME_TYPES = new Set([
  'image/svg+xml',
  'image/png',
  'image/webp',
  'image/jpeg',
  'image/gif',
  'video/mp4',
]);

const ALLOWED_WIDGET_ICON_EXTENSIONS = new Set([
  'svg',
  'png',
  'webp',
  'jpg',
  'jpeg',
  'gif',
  'mp4',
]);

function urlPathnameOnly(raw: string): string {
  try {
    return new URL(raw).pathname;
  } catch {
    return raw.split('#')[0].split('?')[0];
  }
}

/** True when the custom launcher URL is an animated avatar asset (GIF/MP4). */
export function isWidgetAvatarLauncherUrl(url: string | null | undefined): boolean {
  const raw = String(url ?? '').trim();
  if (!raw) return false;
  const ext = urlPathnameOnly(raw).split('.').pop()?.toLowerCase() ?? '';
  return WIDGET_AVATAR_EXTENSIONS.has(ext);
}

/** True when the custom launcher URL is an MP4 video avatar. */
export function isWidgetAvatarVideoUrl(url: string | null | undefined): boolean {
  const raw = String(url ?? '').trim();
  if (!raw) return false;
  return urlPathnameOnly(raw).toLowerCase().endsWith('.mp4');
}

/** File name shown in the custom icon input instead of the full URL. */
export function widgetIconUrlDisplayName(url: string | null | undefined): string {
  const raw = String(url ?? '').trim();
  if (!raw) return '';
  const base = urlPathnameOnly(raw).split('/').pop() ?? '';
  try {
    return decodeURIComponent(base) || raw;
  } catch {
    return base || raw;
  }
}

export function validateWidgetIconFile(
  file: { name: string; size: number; type: string },
): { ok: true } | { ok: false; message: string } {
  const size = Number(file.size ?? 0);
  if (!Number.isFinite(size) || size <= 0) {
    return { ok: false, message: 'Icon file is empty.' };
  }

  const ext = String(file.name ?? '')
    .split('.')
    .pop()
    ?.toLowerCase()
    ?.trim();
  if (!ext || !ALLOWED_WIDGET_ICON_EXTENSIONS.has(ext)) {
    return {
      ok: false,
      message: 'Icon file must be .svg, .png, .webp, .jpg, .jpeg, .gif, or .mp4.',
    };
  }

  const isAvatar = WIDGET_AVATAR_EXTENSIONS.has(ext);
  const maxBytes = isAvatar
    ? MAX_WIDGET_AVATAR_FILE_SIZE_BYTES
    : MAX_WIDGET_ICON_FILE_SIZE_BYTES;
  if (size > maxBytes) {
    return {
      ok: false,
      message: isAvatar
        ? 'Avatar file (GIF/MP4) must be under 1 MB.'
        : 'Icon file must be under 100 KB.',
    };
  }

  const mime = String(file.type ?? '').toLowerCase().trim();
  if (mime && !ALLOWED_WIDGET_ICON_MIME_TYPES.has(mime)) {
    return {
      ok: false,
      message: 'Icon file type is not allowed. Use SVG, PNG, WebP, JPEG, GIF, or MP4.',
    };
  }

  return { ok: true };
}

export type WidgetLauncherIconConfigInput = {
  mode?: unknown;
  lucideIcon?: unknown;
  customIconUrl?: unknown;
} | null | undefined;

function isWidgetLucideIconKey(value: string): value is WidgetLucideIconKey {
  return (WIDGET_LUCIDE_ICON_KEYS as readonly string[]).includes(value);
}

export function normalizeWidgetLauncherIconConfig(
  raw: WidgetLauncherIconConfigInput,
): WidgetLauncherIconConfig {
  if (!raw || typeof raw !== 'object') return { ...DEFAULT_WIDGET_LAUNCHER_ICON };
  const modeRaw = String(raw.mode ?? '').trim().toLowerCase();
  const mode: WidgetLauncherIconMode =
    modeRaw === 'custom_url' ? 'custom_url' : 'lucide';
  const lucideRaw = String(raw.lucideIcon ?? '').trim().toLowerCase();
  const lucideIcon: WidgetLucideIconKey = isWidgetLucideIconKey(lucideRaw)
    ? lucideRaw
    : DEFAULT_WIDGET_LAUNCHER_ICON.lucideIcon;
  const customIconUrl = String(raw.customIconUrl ?? '').trim() || null;
  return {
    mode,
    lucideIcon,
    customIconUrl,
  };
}

export function validateWidgetLauncherIconConfig(
  raw: WidgetLauncherIconConfigInput,
): { ok: true; value: WidgetLauncherIconConfig } | { ok: false; message: string } {
  const normalized = normalizeWidgetLauncherIconConfig(raw);
  if (normalized.mode === 'lucide') {
    return {
      ok: true,
      value: {
        mode: 'lucide',
        lucideIcon: normalized.lucideIcon,
        customIconUrl: null,
      },
    };
  }

  const customUrl = String(normalized.customIconUrl ?? '').trim();
  if (!customUrl) {
    return { ok: false, message: 'Custom icon URL is required.' };
  }
  if (customUrl.length > MAX_CUSTOM_ICON_URL_LENGTH) {
    return { ok: false, message: 'Custom icon URL is too long.' };
  }

  let parsed: URL;
  try {
    parsed = new URL(customUrl);
  } catch {
    return { ok: false, message: 'Custom icon URL must be a valid URL.' };
  }

  if (parsed.protocol !== 'https:') {
    return { ok: false, message: 'Custom icon URL must use HTTPS.' };
  }

  const host = parsed.hostname.toLowerCase();
  if (host === 'localhost' || host.endsWith('.localhost')) {
    return { ok: false, message: 'Custom icon URL must be publicly accessible.' };
  }

  if (!/\.(svg|png|webp|jpg|jpeg|gif|mp4)$/i.test(parsed.pathname)) {
    return {
      ok: false,
      message: 'Custom icon URL must end with .svg, .png, .webp, .jpg, .jpeg, .gif, or .mp4.',
    };
  }

  return {
    ok: true,
    value: {
      mode: 'custom_url',
      lucideIcon: normalized.lucideIcon,
      customIconUrl: parsed.toString(),
    },
  };
}

export function widgetLauncherIconConfigEquals(
  a: WidgetLauncherIconConfig,
  b: WidgetLauncherIconConfig,
): boolean {
  return (
    a.mode === b.mode &&
    a.lucideIcon === b.lucideIcon &&
    (a.customIconUrl ?? null) === (b.customIconUrl ?? null)
  );
}
