import { request } from '../../../utils';
import { API } from '../../../types';
import { ResponseType } from '../response-type';
import { User } from '@api/regions';

export interface PostGetProfileData extends ResponseType {
  user_id: number;
  email: string;
  first_name: string;
  last_name: string;
  username: string;
  avatar: string;
  date_of_birth: string;
  homebase: number;
  homebase2: number | null;
  bio: string;
  links: {
    f?: SocialData;
    t?: SocialData;
    i?: SocialData;
    y?: SocialData;
    www?: SocialData;
    other?: SocialData;
  };
}

export interface PostSetProfileData {
  token: string;
  user?: {
    email?: string;
    first_name?: string;
    last_name?: string;
    date_of_birth?: string;
    username?: string;
    homebase?: number;
    homebase2?: number;
    bio?: string;
    f?: string;
    t?: string;
    i?: string;
    y?: string;
    www?: string;
    other?: string;
  };
  photo?: {
    type: string;
    uri: string;
    name: string;
  };
}

export interface PostSetProfileDataReturn extends ResponseType {
  updated: string[];
  not_updated: string[];
}

export type SocialData = {
  link: string;
  active: 0 | 1;
};

export interface PostGetProfileInfoReturn extends ResponseType {
  username: string;
  email: string;
  first_name: string;
  last_name: string;
  date_of_birth: string;
  avatar_full_size: string;
  avatar: string;
  bio: string;
  links: {
    f?: SocialData;
    t?: SocialData;
    i?: SocialData;
    y?: SocialData;
    www?: SocialData;
    other?: SocialData;
  };
  homebase: number;
  homebase_name: string;
  homebase_flag: string;
  homebase2: number;
  homebase2_name: string;
  homebase2_flag: string;
  series: Series[];
  scores: Score[];
}

export type Series = {
  id: number;
  score: string;
  name: string;
  icon: string;
  app_icon: string;
};

export type Score = {
  name: string;
  score: number;
};

export interface PostGetProfileRegionsReturn extends ResponseType {
  data: NM | MQP | UN_UNP_TCC | YES | SLOW | WHS;
}

export type NM = {
  all_count: number;
  firsts: Record<string, number | null>;
  last: Record<string, number | null>;
  megaregions: {
    id: number;
    name: string;
    regions: {
      id: number;
      name: string;
      flag1: string;
      flag2: string | null;
    }[];
    transits: number[];
    visits: number[];
  }[];
  transits_count: number;
  visits_count: number;
};

export type MQP = {
  all_count: number;
  megaregions: {
    id: number;
    name: string;
    regions: {
      id: number;
      name: string;
      flag1: string;
      flag2: string | null;
    }[];
    transits: number[];
    visits: number[];
  }[];
  transits_count: number;
  visits_count: number;
};

export type UN_UNP_TCC = [
  {
    name: string;
    name_en: string;
    flag1: string;
    flag2: string | null;
  }[],
  string[],
  number,
  number
];

export type YES = [
  {
    id: number;
    name: string;
    name_en: string;
    flag1: string;
    flag2: string | null;
  }[],
  Record<
    string,
    {
      year: number;
      score: number;
      country: string;
    }
  >
];

export type SLOW = [
  {
    country_id: number;
    country: string;
    flag: string;
    mega: number[];
    visited: 0 | 1;
    slow11: 0 | 1;
    slow31: 0 | 1;
    slow101: 0 | 1;
    yes: number;
  }[],
  Record<string, string>
];

export type WHS = {
  name: string;
  flag: string;
  visited: boolean;
}[];

export interface PostGetProfileDataReturn extends ResponseType {
  data: {
    can_authenticate: 0 | 1;
    can_be_authenticated: 0 | 1;
    can_see_updates: 0 | 1;
    can_send_friend_request: 0 | 1;
    friend_request_received: 0 | 1;
    friend_request_sent: 0 | 1;
    friend_db_id: number;
    friends: {
      avatar: string | null;
      user_id: number;
      first_name: string;
      last_name: string;
      flag: string;
    }[];
    interviews: {
      link: string;
      year: number;
    }[];
    is_friend: 0 | 1;
    own_profile: 0 | 1;
    png_map: 0 | 1;
    scores: {
      rank_country: number;
      rank_nm: number;
      rank_tbt: number;
      score_kye: number;
      score_mqp: number;
      score_mtp: number;
      score_nm: number;
      score_slow: string;
      score_slow11: string;
      score_slow31: string;
      score_slow101: string;
      score_tbt: number;
      score_tcc: number;
      score_un: number;
      score_unp: number;
      score_whs: number;
      score_yes: number;
      series: string;
      series_max: string;
      series_total: string;
    };
    series: Series[];
    user_data: {
      age: number;
      alive: 0 | 1;
      auth: 0 | 1;
      avatar: string | null;
      badge_nm: number | null;
      badge_tbt: 0 | 1;
      badge_un: 0 | 1;
      badge_un_25: 0 | 1;
      badge_un_50: 0 | 1;
      badge_un_75: 0 | 1;
      badge_un_100: 0 | 1;
      badge_un_150: 0 | 1;
      badge_un_193: 0 | 1;
      badge_premium: 0 | 1;
      badges: number;
      bio: string;
      email: string;
      first_name: string;
      flag1: string;
      flag2: string | null;
      last_name: string;
      last_seen_date: string | null;
      last_seen_in: string | null;
      links_json: string;
      offline: number | null;
      patreon: 0 | 1;
      supreme: 0 | 1;
      ukr: 0 | 1;
      homeregion: string;
      badge_ghost: 0 | 1;
    };
    location_sharing: boolean;
    location_last_seen_region: string | null;
    location_last_seen_flag: string | null;
    location_last_seen_date: string;
    location_last_seen_location: {
      lat: number;
      lng: number;
    };
  };
}

export interface PostGetProfileUpdatesReturn extends ResponseType {
  data: {
    can_see_updates: 0 | 1;
    updates: {
      un_visited: number;
      un_new: number;
      unp_visited: number;
      unp_new: number;
      nm_visited: number;
      nm_new: number;
      new_dare: number;
      new_series: number;
      new_whs: number;
    };
  };
}

export interface PostGetMapYearsReturn extends ResponseType {
  data: {
    map_years: number[];
    map_count_nm: { [key: string]: number };
    map_count_un: { [key: string]: number };
    map_count_in_nm: { [key: string]: number };
    map_count_in_un: { [key: string]: number };
    max_nm: number;
    max_un: number;
  };
}

export interface NewNM {
  new_nm: {
    flag1: string;
    flag2: string | null;
    id: number;
    name: string;
  }[];
  visited_regions: {
    flag1: string;
    flag2: string | null;
    id: number;
    name: string;
  }[];
}

export interface UnOrUnp {
  visited_countries: {
    country: string;
    flag: string;
    id: number;
  }[];
}

export interface Dare {
  flag1: string;
  flag2: string | null;
  id: number;
  name: string;
}

export interface SeriesOrWhs {
  icon: string;
  id: number;
  item: string;
  series: string;
  app_icon: string;
}

type PostGetUpdateReturnData<T extends string> = T extends 'nm'
  ? NewNM
  : T extends 'un' | 'unp'
    ? UnOrUnp
    : T extends 'dare'
      ? Dare[]
      : T extends 'series' | 'whs'
        ? SeriesOrWhs[]
        : never;

export interface PostGetUpdateReturn<T extends string> extends ResponseType {
  data: PostGetUpdateReturnData<T>;
}

export interface PostGetProfileSeriesDataReturn extends ResponseType {
  series_name: string;
  series_icon: string;
  items_grouped: {
    name: string;
    icon: string | null;
    items: {
      item_id: number;
      name: string;
    }[];
  }[];
}

export const userApi = {
  getProfileData: (token: string) =>
    request.postForm<PostGetProfileData>(API.GET_USER_SETTINGS_DATA, { token }),
  setProfileData: (data: PostSetProfileData) => {
    const formData = new FormData();

    formData.append('token', data.token);
    formData.append('user', JSON.stringify(data.user));
    if (data.photo && data.photo?.uri) {
      formData.append('photo', {
        type:
          data.photo.type === 'image'
            ? data.photo.type + '/' + data.photo.uri.split('.').pop()!
            : data.photo.type,
        uri: data.photo.uri,
        name: data.photo.name
      } as unknown as Blob);
    }

    return request.postForm<PostSetProfileDataReturn>(API.SET_USER_SETTINGS_DATA, formData);
  },
  getProfileInfo: (token: string) =>
    request.postForm<PostGetProfileInfoReturn>(API.PROFILE_INFO, { token }),
  getProfileInfoPublic: (uid: number) =>
    request.postForm<Exclude<PostGetProfileInfoReturn, { email: null }>>(API.PROFILE_INFO_PUBLIC, {
      uid
    }),
  getProfileRegions: (token: string, uid: number, type: string) =>
    request.postForm<PostGetProfileRegionsReturn>(API.GET_PROFILE_REGIONS, { token, uid, type }),
  getProfileInfoData: (token: string, profile_id: number) =>
    request.postForm<PostGetProfileDataReturn>(API.GET_PROGILE_DATA, {
      token,
      profile_id
    }),
  getProfileUpdates: (token: string, profile_id: number) =>
    request.postForm<PostGetProfileUpdatesReturn>(API.GET_PROFILE_UPDATES, {
      token,
      profile_id
    }),
  setNotificationToken: (token: string, platform: string, n_token: string) =>
    request.postForm<ResponseType>(API.SET_NOTIFICATION_TOKEN, {
      token,
      platform,
      n_token
    }),
  getMapYears: (token: string, profile_id: number) =>
    request.postForm<PostGetMapYearsReturn>(API.GET_MAP_YEARS, { token, profile_id }),
  getUpdate: <T extends string>(token: string, profile_id: number, type: T) =>
    request.postForm<PostGetUpdateReturn<T>>(API.GET_UPDATE, { token, profile_id, type }),
  autenticate: (token: string, profile_id: number) =>
    request.postForm<ResponseType>(API.AUTHENTICATE, { token, profile_id }),
  updateEmail: (token: string, email: string) =>
    request.postForm<ResponseType>(API.UPDATE_EMAIL, { token, email }),
  getProfileSeriesData: (token: string, user_id: number, series_id: number) =>
    request.postForm<PostGetProfileSeriesDataReturn>(API.GET_PROFILE_SERIES_DATA, {
      token,
      user_id,
      series_id
    })
};
