import { ContactData, Documento, Pagamento, Reserva, ReservaData, SocialMedia } from "../types";
import AsyncStorage from "@react-native-async-storage/async-storage";

const STORAGE_KEYS = {
  RESERVAS: "@cruiseLovers:reservas",
  RESERVA_DETAIL: "@cruiseLovers:reserva:",
  RESERVA_FULL: "@cruiseLovers:reservaFull:",
  CONTACTS: "@cruiseLovers:contacts",
  SOCIALS: "@cruiseLovers:socials",
  USER_INFO: "@cruiseLovers:userInfo",
  LAST_SYNC: "@cruiseLovers:lastSync",
  CACHE_VERSION: "@cruiseLovers:cacheVersion",
} as const;

export interface CachedReservaFull {
  reservaData: ReservaData;
  pagamentos: Pagamento[];
  documentos: Documento[];
  cachedAt: string;
}

const CACHE_VERSION = "1.0.0";

/**
 * Armazena a lista de reservas no cache
 */
export const cacheReservas = async (reservas: Reserva[]): Promise<void> => {
  try {
    await AsyncStorage.setItem(STORAGE_KEYS.RESERVAS, JSON.stringify(reservas));
    await AsyncStorage.setItem(STORAGE_KEYS.LAST_SYNC, new Date().toISOString());
  } catch (error) {
    console.error("Erro ao armazenar reservas no cache:", error);
  }
};

/**
 * Obtém a lista de reservas do cache
 */
export const getCachedReservas = async (): Promise<Reserva[] | null> => {
  try {
    const cached = await AsyncStorage.getItem(STORAGE_KEYS.RESERVAS);
    if (cached) {
      return JSON.parse(cached);
    }
    return null;
  } catch (error) {
    console.error("Erro ao obter reservas do cache:", error);
    return null;
  }
};

/**
 * Armazena os detalhes de uma reserva no cache
 */
export const cacheReservaDetail = async (id: string, reservaData: ReservaData): Promise<void> => {
  try {
    const key = `${STORAGE_KEYS.RESERVA_DETAIL}${id}`;
    await AsyncStorage.setItem(key, JSON.stringify(reservaData));
  } catch (error) {
    console.error(`Erro ao armazenar detalhes da reserva ${id} no cache:`, error);
  }
};

/**
 * Obtém os detalhes de uma reserva do cache
 */
export const getCachedReservaDetail = async (id: string): Promise<ReservaData | null> => {
  try {
    const key = `${STORAGE_KEYS.RESERVA_DETAIL}${id}`;
    const cached = await AsyncStorage.getItem(key);
    if (cached) {
      return JSON.parse(cached);
    }
    return null;
  } catch (error) {
    console.error(`Erro ao obter detalhes da reserva ${id} do cache:`, error);
    return null;
  }
};

/**
 * Armazena os dados completos de uma reserva (reserva + pagamentos + documentos) no cache
 */
export const cacheReservaFull = async (referencia: string, data: CachedReservaFull): Promise<void> => {
  try {
    const key = `${STORAGE_KEYS.RESERVA_FULL}${referencia}`;
    await AsyncStorage.setItem(key, JSON.stringify(data));
  } catch (error) {
    console.error(`Erro ao armazenar dados completos da reserva ${referencia} no cache:`, error);
  }
};

/**
 * Obtém os dados completos de uma reserva do cache
 */
export const getCachedReservaFull = async (referencia: string): Promise<CachedReservaFull | null> => {
  try {
    const key = `${STORAGE_KEYS.RESERVA_FULL}${referencia}`;
    const cached = await AsyncStorage.getItem(key);
    return cached ? (JSON.parse(cached) as CachedReservaFull) : null;
  } catch (error) {
    console.error(`Erro ao obter dados completos da reserva ${referencia} do cache:`, error);
    return null;
  }
};

/**
 * Armazena os contactos no cache
 */
export const cacheContacts = async (contactData: ContactData, socials: SocialMedia[]): Promise<void> => {
  try {
    await AsyncStorage.setItem(STORAGE_KEYS.CONTACTS, JSON.stringify(contactData));
    await AsyncStorage.setItem(STORAGE_KEYS.SOCIALS, JSON.stringify(socials));
    await AsyncStorage.setItem(STORAGE_KEYS.LAST_SYNC, new Date().toISOString());
  } catch (error) {
    console.error("Erro ao armazenar contactos no cache:", error);
  }
};

/**
 * Obtém os contactos do cache
 */
export const getCachedContacts = async (): Promise<{ contactData: ContactData | null; socials: SocialMedia[] }> => {
  try {
    const cachedContact = await AsyncStorage.getItem(STORAGE_KEYS.CONTACTS);
    const cachedSocials = await AsyncStorage.getItem(STORAGE_KEYS.SOCIALS);
    
    return {
      contactData: cachedContact ? JSON.parse(cachedContact) : null,
      socials: cachedSocials ? JSON.parse(cachedSocials) : [],
    };
  } catch (error) {
    console.error("Erro ao obter contactos do cache:", error);
    return { contactData: null, socials: [] };
  }
};

/**
 * Obtém a data da última sincronização
 */
export const getLastSyncDate = async (): Promise<Date | null> => {
  try {
    const lastSync = await AsyncStorage.getItem(STORAGE_KEYS.LAST_SYNC);
    return lastSync ? new Date(lastSync) : null;
  } catch {
    return null;
  }
};

/**
 * Limpa todo o cache
 */
export const clearCache = async (): Promise<void> => {
  try {
    const keys = await AsyncStorage.getAllKeys();
    const appKeys = keys.filter(key => key.startsWith("@cruiseLovers:"));
    await AsyncStorage.multiRemove(appKeys);
  } catch (error) {
    console.error("Erro ao limpar cache:", error);
  }
};

/**
 * Limpa apenas o cache de reservas
 */
export const clearReservasCache = async (): Promise<void> => {
  try {
    const keys = await AsyncStorage.getAllKeys();
    const reservaKeys = keys.filter(
      (key) =>
        key === STORAGE_KEYS.RESERVAS ||
        key.startsWith(STORAGE_KEYS.RESERVA_DETAIL) ||
        key.startsWith(STORAGE_KEYS.RESERVA_FULL),
    );
    await AsyncStorage.multiRemove(reservaKeys);
  } catch (error) {
    console.error("Erro ao limpar cache de reservas:", error);
  }
};

/** Dados de sessão do utilizador — mantém contactos da agência (partilhados). */
export const clearUserSessionCache = async (): Promise<void> => {
  try {
    const keys = await AsyncStorage.getAllKeys();
    const sessionKeys = keys.filter(
      (key) =>
        key.startsWith("@cruiseLovers:") &&
        key !== STORAGE_KEYS.CONTACTS &&
        key !== STORAGE_KEYS.SOCIALS,
    );
    await AsyncStorage.multiRemove(sessionKeys);
  } catch (error) {
    console.error("Erro ao limpar cache da sessão:", error);
  }
};

/**
 * Armazena informações do perfil no cache
 */
export const cacheUserInfo = async (userInfo: any): Promise<void> => {
  try {
    await AsyncStorage.setItem(STORAGE_KEYS.USER_INFO, JSON.stringify(userInfo));
  } catch (error) {
    console.error("Erro ao armazenar perfil no cache:", error);
  }
};

/**
 * Obtém informações do perfil do cache
 */
export const getCachedUserInfo = async (): Promise<any | null> => {
  try {
    const cached = await AsyncStorage.getItem(STORAGE_KEYS.USER_INFO);
    return cached ? JSON.parse(cached) : null;
  } catch (error) {
    console.error("Erro ao obter perfil do cache:", error);
    return null;
  }
};

/**
 * Obtém informações sobre o tamanho do cache
 */
export const getCacheInfo = async (): Promise<{ size: number; lastSync: Date | null }> => {
  try {
    const keys = await AsyncStorage.getAllKeys();
    const appKeys = keys.filter(key => key.startsWith("@cruiseLovers:"));
    const items = await AsyncStorage.multiGet(appKeys);
    
    let totalSize = 0;
    items.forEach(([_, value]) => {
      if (value) {
        totalSize += value.length;
      }
    });
    
    const lastSync = await getLastSyncDate();
    
    return {
      size: totalSize,
      lastSync,
    };
  } catch (error) {
    console.error("Erro ao obter informações do cache:", error);
    return { size: 0, lastSync: null };
  }
};
