import AsyncStorage from '@react-native-async-storage/async-storage';
import type { UserProfileV1_2_Extended } from '@/src/features/userProfileScoring';

/**
 * 本地存储 key 统一管理，避免 UI 里散落硬编码
 */
const KEY_ONBOARDING_COMPLETED = 'onboarding.completed';
const KEY_PUSH_PROMPT_STATE = 'push.promptState';
const KEY_CONTENT_REACTIONS = 'content.reactions';
const KEY_FAVORITES_ITEMS = 'favorites.items';
const KEY_CONSENT_ACCEPTED = 'consent.accepted';
const KEY_USER_PROFILE = 'user.profile';
const KEY_USER_PROFILE_SCORING = 'user.profileScoring';
const KEY_RECO_FEED_CACHE = 'reco.feedCache';
const KEY_RECO_FEED_HISTORY = 'reco.feedHistory';
const KEY_UI_THEME_MODE = 'ui.theme.mode';
const KEY_DAILY_REMINDER_SETTINGS = 'dailyReminder.settings';

export type PushPromptState = 'enabled' | 'skipped' | 'unknown';
export type Reaction = 'like' | 'dislike';
export type ReactionsMap = Record<string, Reaction>;
export type ThemeMode = 'scenery' | 'color';
export type UserProfile = {
  name?: string;
  intents?: string[];
};

/**
 * 用户画像（问卷打分输出）
 * 说明：用于推荐/Push/Widget 统一复用；结构以 `src/features/userProfileScoring` 输出为准。
 */
export type UserProfileScoring = UserProfileV1_2_Extended;
export type DailyReminderSettings = {
  timesPerDay: number;
  pushEnabled: boolean;
};

export type RecoFeedCacheItem = {
  content_id: number;
  text: string;
};

export type RecoFeedCache = {
  saved_at: string; // ISO8601
  items: RecoFeedCacheItem[];
  meta?: Record<string, unknown>;
};

/**
 * Feed 链路可观测输入（用于下一次请求携带给后端）
 *
 * - already_recommended_ids：本设备已下发过的内容（避免重复下发）
 * - touched_or_viewed_ids：本设备用户已看过/划过的内容（用于频控/去重/降重复）
 *
 * 说明：后端不需要“实时知道”，只要在下一次拉取时带上即可。
 */
export type RecoFeedHistory = {
  updated_at: string; // ISO8601
  already_recommended_ids: number[];
  touched_or_viewed_ids: number[];
};


async function getJson<T>(key: string, fallback: T): Promise<T> {
  const raw = await AsyncStorage.getItem(key);
  if (!raw) return fallback;
  try {
    return JSON.parse(raw) as T;
  } catch {
    return fallback;
  }
}

async function setJson<T>(key: string, value: T): Promise<void> {
  await AsyncStorage.setItem(key, JSON.stringify(value));
}

export async function getOnboardingCompleted(): Promise<boolean> {
  const raw = await AsyncStorage.getItem(KEY_ONBOARDING_COMPLETED);
  return raw === 'true';
}

export async function setOnboardingCompleted(completed: boolean): Promise<void> {
  await AsyncStorage.setItem(KEY_ONBOARDING_COMPLETED, completed ? 'true' : 'false');
}

export async function getPushPromptState(): Promise<PushPromptState> {
  const raw = await AsyncStorage.getItem(KEY_PUSH_PROMPT_STATE);
  if (raw === 'enabled' || raw === 'skipped' || raw === 'unknown') return raw;
  return 'unknown';
}

export async function setPushPromptState(state: PushPromptState): Promise<void> {
  await AsyncStorage.setItem(KEY_PUSH_PROMPT_STATE, state);
}

export async function getReactions(): Promise<ReactionsMap> {
  return await getJson<ReactionsMap>(KEY_CONTENT_REACTIONS, {});
}

export async function setReaction(contentId: string, reaction: Reaction): Promise<void> {
  const next = await getReactions();
  next[contentId] = reaction;
  await setJson(KEY_CONTENT_REACTIONS, next);
}

export type FavoriteItem = {
  favId: string; // 唯一标识，支持重复点赞同一文案
  id: string;
  date: string;
  themeMode: ThemeMode;
  background: string; // 颜色值或图片路径
};

export async function getFavorites(): Promise<FavoriteItem[]> {
  return await getJson<FavoriteItem[]>(KEY_FAVORITES_ITEMS, []);
}

export async function addFavorite(item: FavoriteItem): Promise<void> {
  const list = await getFavorites();
  // 允许重复点赞，不再根据 id 去重
  const newList = [item, ...list];
  console.log('Adding to favorites, new list size:', newList.length);
  await setJson(KEY_FAVORITES_ITEMS, newList);
}

export async function removeFavorite(favId: string): Promise<void> {
  const list = await getFavorites();
  const next = list.filter(item => item.favId !== favId);
  await setJson(KEY_FAVORITES_ITEMS, next);
}

export async function getConsentAccepted(): Promise<boolean> {
  const raw = await AsyncStorage.getItem(KEY_CONSENT_ACCEPTED);
  return raw === 'true';
}

export async function setConsentAccepted(accepted: boolean): Promise<void> {
  await AsyncStorage.setItem(KEY_CONSENT_ACCEPTED, accepted ? 'true' : 'false');
}

export async function getThemeMode(): Promise<ThemeMode> {
  const raw = await AsyncStorage.getItem(KEY_UI_THEME_MODE);
  if (raw === 'scenery' || raw === 'color') return raw;
  return 'scenery';
}

export async function setThemeMode(mode: ThemeMode): Promise<void> {
  await AsyncStorage.setItem(KEY_UI_THEME_MODE, mode);
}

export async function getUserProfile(): Promise<UserProfile> {
  return await getJson<UserProfile>(KEY_USER_PROFILE, {});
}

export async function setUserProfile(profile: UserProfile): Promise<void> {
  const current = await getUserProfile();
  await setJson(KEY_USER_PROFILE, { ...current, ...profile });
}

export async function getUserProfileScoring(): Promise<UserProfileScoring | null> {
  const raw = await AsyncStorage.getItem(KEY_USER_PROFILE_SCORING);
  if (!raw) return null;
  try {
    return JSON.parse(raw) as UserProfileScoring;
  } catch {
    return null;
  }
}

export async function setUserProfileScoring(profile: UserProfileScoring): Promise<void> {
  await setJson(KEY_USER_PROFILE_SCORING, profile);
}

export async function getRecoFeedCache(): Promise<RecoFeedCache | null> {
  const raw = await AsyncStorage.getItem(KEY_RECO_FEED_CACHE);
  if (!raw) return null;
  try {
    return JSON.parse(raw) as RecoFeedCache;
  } catch {
    return null;
  }
}

export async function setRecoFeedCache(cache: RecoFeedCache): Promise<void> {
  await setJson(KEY_RECO_FEED_CACHE, cache);
}

export async function getRecoFeedHistory(): Promise<RecoFeedHistory> {
  const raw = await AsyncStorage.getItem(KEY_RECO_FEED_HISTORY);
  if (!raw) {
    return {
      updated_at: new Date().toISOString(),
      already_recommended_ids: [],
      touched_or_viewed_ids: [],
    };
  }
  try {
    const parsed = JSON.parse(raw) as Partial<RecoFeedHistory>;
    return {
      updated_at: typeof parsed.updated_at === 'string' ? parsed.updated_at : new Date().toISOString(),
      already_recommended_ids: Array.isArray(parsed.already_recommended_ids)
        ? parsed.already_recommended_ids.filter((x) => Number.isFinite(x)).map((x) => Number(x))
        : [],
      touched_or_viewed_ids: Array.isArray(parsed.touched_or_viewed_ids)
        ? parsed.touched_or_viewed_ids.filter((x) => Number.isFinite(x)).map((x) => Number(x))
        : [],
    };
  } catch {
    return {
      updated_at: new Date().toISOString(),
      already_recommended_ids: [],
      touched_or_viewed_ids: [],
    };
  }
}

export async function setRecoFeedHistory(history: RecoFeedHistory): Promise<void> {
  await setJson(KEY_RECO_FEED_HISTORY, history);
}

function uniqKeepLatest(list: number[], max: number): number[] {
  const seen = new Set<number>();
  const out: number[] = [];
  for (let i = list.length - 1; i >= 0; i -= 1) {
    const v = list[i];
    if (!Number.isFinite(v)) continue;
    if (seen.has(v)) continue;
    seen.add(v);
    out.push(v);
    if (out.length >= max) break;
  }
  return out.reverse();
}

export async function recordRecoFeedServed(contentIds: number[]): Promise<void> {
  if (!contentIds?.length) return;
  const h = await getRecoFeedHistory();
  const next = {
    ...h,
    updated_at: new Date().toISOString(),
    already_recommended_ids: uniqKeepLatest([...h.already_recommended_ids, ...contentIds], 500),
  };
  await setRecoFeedHistory(next);
}

export async function recordRecoFeedTouched(contentId: number): Promise<void> {
  if (!Number.isFinite(contentId)) return;
  const h = await getRecoFeedHistory();
  const next = {
    ...h,
    updated_at: new Date().toISOString(),
    touched_or_viewed_ids: uniqKeepLatest([...h.touched_or_viewed_ids, contentId], 500),
  };
  await setRecoFeedHistory(next);
}

export async function getDailyReminderSettings(): Promise<DailyReminderSettings> {
  const s = await getJson<DailyReminderSettings>(KEY_DAILY_REMINDER_SETTINGS, {
    timesPerDay: 3,
    pushEnabled: false,
  });
  const timesPerDay = Number.isFinite(s.timesPerDay) ? s.timesPerDay : 3;
  return {
    timesPerDay: Math.min(10, Math.max(1, Math.round(timesPerDay))),
    pushEnabled: Boolean(s.pushEnabled),
  };
}

export async function setDailyReminderSettings(settings: DailyReminderSettings): Promise<void> {
  const timesPerDay = Math.min(10, Math.max(1, Math.round(settings.timesPerDay)));
  await setJson(KEY_DAILY_REMINDER_SETTINGS, {
    timesPerDay,
    pushEnabled: Boolean(settings.pushEnabled),
  });
}
