import { ref, computed } from 'vue';
import { isValidAvatarKey, playerAvatarUrl, randomAvatarKey } from '@thebet365/shared';
import api from '../api';

type ProfileData = {
  id?: string | number;
  username?: string;
  locale?: string;
  preferences?: {
    phone?: string | null;
    email?: string | null;
    avatarKey?: string | null;
    allowPasswordChange?: boolean;
    allowUsernameChange?: boolean;
    viewablePassword?: string | null;
  };
  wallet?: { availableBalance: string; frozenBalance: string };
};

const AVATAR_CACHE_PREFIX = 'player_avatar_key:';

const profileRaw = ref<ProfileData | null>(null);
const loading = ref(false);
let loadPromise: Promise<void> | null = null;
let assigningDefault = false;
let visibilityBound = false;

function profileSeed(profile: ProfileData | null): string {
  if (!profile) return '';
  return String(profile.id ?? profile.username ?? '');
}

function readCachedAvatarKey(seed: string): string | null {
  if (!seed) return null;
  try {
    const key = localStorage.getItem(`${AVATAR_CACHE_PREFIX}${seed}`);
    return key && isValidAvatarKey(key) ? key : null;
  } catch {
    return null;
  }
}

function writeCachedAvatarKey(seed: string, key: string) {
  if (!seed || !key) return;
  try {
    localStorage.setItem(`${AVATAR_CACHE_PREFIX}${seed}`, key);
  } catch {
    /* ignore */
  }
}

function applyAvatarKey(key: string | null) {
  if (!profileRaw.value) {
    profileRaw.value = { preferences: { avatarKey: key } };
    return;
  }
  profileRaw.value = {
    ...profileRaw.value,
    preferences: {
      ...profileRaw.value.preferences,
      avatarKey: key,
    },
  };
}

async function ensureDefaultAvatar() {
  if (assigningDefault || !profileRaw.value) return;

  const seed = profileSeed(profileRaw.value);
  const current =
    profileRaw.value.preferences?.avatarKey ?? readCachedAvatarKey(seed);
  if (current && isValidAvatarKey(current)) {
    applyAvatarKey(current);
    return;
  }

  assigningDefault = true;
  const key = randomAvatarKey(seed);
  try {
    try {
      await api.patch('/player/profile', { avatarKey: key });
    } catch {
      /* 数据库未迁移等情况仍展示本地头像 */
    }
    applyAvatarKey(key);
    writeCachedAvatarKey(seed, key);
  } finally {
    assigningDefault = false;
  }
}

async function loadProfile(force = false) {
  if (loadPromise) return loadPromise;

  if (!force && profileRaw.value) {
    await ensureDefaultAvatar();
    return;
  }

  loadPromise = (async () => {
    loading.value = true;
    try {
      const { data } = await api.get('/player/profile');
      profileRaw.value = data.data ?? null;
      await ensureDefaultAvatar();
    } finally {
      loading.value = false;
      loadPromise = null;
    }
  })();

  return loadPromise;
}

function refreshProfile() {
  return loadProfile(true);
}

function bindProfileVisibilityRefresh() {
  if (visibilityBound || typeof document === 'undefined') return;
  visibilityBound = true;
  document.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'visible' && profileRaw.value) {
      void loadProfile(true);
    }
  });
}

const avatarKey = computed(() => {
  const saved = profileRaw.value?.preferences?.avatarKey;
  if (saved && isValidAvatarKey(saved)) return saved;

  const seed = profileSeed(profileRaw.value);
  if (!seed) return null;

  const cached = readCachedAvatarKey(seed);
  if (cached) return cached;

  return randomAvatarKey(seed);
});
const avatarUrl = computed(() => playerAvatarUrl(avatarKey.value));

function setAvatarKey(key: string | null) {
  applyAvatarKey(key);
  const seed = profileSeed(profileRaw.value);
  if (key && seed) writeCachedAvatarKey(seed, key);
}

export function usePlayerProfile() {
  return {
    profileRaw,
    loading,
    avatarKey,
    avatarUrl,
    loadProfile,
    refreshProfile,
    bindProfileVisibilityRefresh,
    setAvatarKey,
  };
}
