import { fetchList, fetchStatistic } from '@api/statistics';
import { StoreType, storage } from 'src/storage';

const NAMESPACE = 'statistics';

function saveData<T>(key: string, data: T) {
  const namespacedKey = `${NAMESPACE}:${key}`;
  const jsonData = JSON.stringify(data);
  storage.set(namespacedKey, jsonData);
}

function loadData<T>(key: string): T | null {
  const namespacedKey = `${NAMESPACE}:${key}`;
  const jsonData = storage.get(namespacedKey, StoreType.STRING) as string;

  return jsonData ? JSON.parse(jsonData) : null;
}

function structureList(listData: Sublist[]) {
  saveData('list', listData);
}

export async function fetchAndSaveStatistics(token: string) {
  const list = await fetchList(token);

  if (list && list.result === 'OK') {
    structureList(list.data);

    for (const category of list.data) {
      for (const item of category.list) {
        const statsData = await fetchStatistic(token, item.url1, item.url2 ?? 'null');

        if (statsData && statsData.result === 'OK') {
          const statsKey = item.url2 ? `stats_${item.url1}_${item.url2}` : `stats_${item.url1}`;

          saveData(statsKey, JSON.stringify(statsData.data));
        }
      }
    }
  }
}

export function getStatistic(url1: string, url2?: string | null): Statistic | null {
  const statsKey = `stats_${url1}${url2 ? `_${url2}` : ''}`;
  return loadData<Statistic>(statsKey);
}

export function getList(): List[] | null {
  return loadData<List[]>('list');
}

export interface ListData {
  name: string;
  url1: string;
  url2?: string | null;
}

interface List {
  name: string;
  list?: ListData[];
  sublists?: Sublist[];
}

interface Sublist {
  name: string;
  list: ListData[];
}

interface StructuredData {
  [key: string]: List;
}

export type ListTypesArray =
  | Type1[]
  | Type2[]
  | Type3[]
  | Type4[]
  | Type5[]
  | Type6[]
  | Type7[]
  | Type8[]
  | Type9[];

export type ListType = Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7 | Type8 | Type9;

export interface Statistic {
  data: {
    url1: string;
    url2: string;
    type: number;
    name: string;
    comment: string;
    ranking: ListTypesArray;
  }[];
}

export type StatisticType = {
  url1: string;
  url2: string;
  type: number;
  name: string;
  comment: string;
  ranking: ListTypesArray;
};

export interface Type1 {
  cnt: number;
  country: string;
  flag: string;
  region_id: number;
  region_name: string;
}

export interface Type2 {
  cnt: number;
  dare_flag: string;
  dare_id: number;
  dare_name: string;
  mega_id: number;
  mega_name: string;
}

export interface Type3 {
  year: number;
  user: number;
  cnt: number;
  first_name: string;
  last_name: string;
  flag: string;
  score?: string;
  nation?: string;
  user_count?: number;
  visited_regions?: number;
}

export interface Type4 {
  cnt: number;
  country: string;
  flag: string;
  mega_id: number;
  megaregion: string;
  region_id: number;
  region_name: string;
}

export interface Type5 {
  cnt: number;
  flag: string;
  region_id: number;
  region_name: string;
}

export interface Type6 {
  cnt: number;
  country: string;
  country_flag: string;
  region: string;
  region_flag: string;
  region_id: number;
}

export interface Type7 {
  cnt: number;
  country_name: string;
  flag: string;
}

export interface Type8 {
  cnt: number;
  country: string;
  flag: string;
  mega_id: number;
  mega_name: string;
}

export interface Type9 {
  flag: string;
  nation: string;
  score: string;
  user_count: number;
  visited_countries: number;
}

export interface Type10 {
  cnt: number;
  flags: string[];
  item_id: number;
  item_name: string;
  series_icon: string;
  series_id: number;
  series_name: string;
}
