const STORAGE_KEY = 'tkmind_h5_user_avatar';
const MAX_BYTES = 2 * 1024 * 1024;
const OUTPUT_SIZE = 128;

const ACCEPTED_TYPES = new Set(['image/jpeg', 'image/png', 'image/webp', 'image/gif']);

export const AVATAR_CHANGED_EVENT = 'tkmind-avatar-changed';
export const AVATAR_PICKER_OPEN_EVENT = 'tkmind-avatar-picker-open';

let avatarPickerInput: HTMLInputElement | null = null;

export function registerAvatarPickerInput(input: HTMLInputElement | null): void {
  avatarPickerInput = input;
}

export function getAvatarPickerInput(): HTMLInputElement | null {
  return avatarPickerInput;
}

export function openAvatarPicker(): void {
  if (avatarPickerInput) {
    avatarPickerInput.click();
    return;
  }
  window.dispatchEvent(new Event(AVATAR_PICKER_OPEN_EVENT));
}

export function loadUserAvatar(): string | null {
  try {
    return localStorage.getItem(STORAGE_KEY);
  } catch {
    return null;
  }
}

export function saveUserAvatar(dataUrl: string): void {
  localStorage.setItem(STORAGE_KEY, dataUrl);
}

export function clearUserAvatar(): void {
  localStorage.removeItem(STORAGE_KEY);
}

export function notifyAvatarChanged(): void {
  window.dispatchEvent(new Event(AVATAR_CHANGED_EVENT));
}

function loadImage(src: string): Promise<HTMLImageElement> {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.onerror = () => reject(new Error('图片加载失败'));
    img.src = src;
  });
}

function cropToSquare(img: HTMLImageElement): HTMLCanvasElement {
  const side = Math.min(img.width, img.height);
  const sx = (img.width - side) / 2;
  const sy = (img.height - side) / 2;
  const canvas = document.createElement('canvas');
  canvas.width = OUTPUT_SIZE;
  canvas.height = OUTPUT_SIZE;
  const ctx = canvas.getContext('2d');
  if (!ctx) throw new Error('无法处理图片');
  ctx.drawImage(img, sx, sy, side, side, 0, 0, OUTPUT_SIZE, OUTPUT_SIZE);
  return canvas;
}

export async function processAvatarFile(file: File): Promise<string> {
  if (!ACCEPTED_TYPES.has(file.type)) {
    throw new Error('仅支持 JPG、PNG、WebP 或 GIF');
  }
  if (file.size > MAX_BYTES) {
    throw new Error('图片不能超过 2MB');
  }

  const objectUrl = URL.createObjectURL(file);
  try {
    const img = await loadImage(objectUrl);
    const canvas = cropToSquare(img);
    const dataUrl = canvas.toDataURL('image/jpeg', 0.88);
    if (dataUrl.length > 120_000) {
      throw new Error('图片过大，请换一张更小的图片');
    }
    return dataUrl;
  } finally {
    URL.revokeObjectURL(objectUrl);
  }
}
