import Taro from '@tarojs/taro';

import { PageUrl } from '@/constants/app';
import { CollectEventName } from '@/constants/event';
import { GenderType, MaterialViewSource } from '@/constants/material';
import { MessageSubscribeIds } from '@/constants/subscribe';
import http from '@/http';
import { API } from '@/http/api';
import { RESPONSE_ERROR_INFO } from '@/http/constant';
import { HttpError } from '@/http/error';
import {
  GetAnchorListRequest,
  GetAnchorListResponse,
  GetReadProfileRequest,
  GetShareProfileRequest,
  MaterialProfile,
  MaterialVideoInfo,
  UpdateProfileStatusRequest,
} from '@/types/material';
import { oncePromise } from '@/utils/common';
import { collectEvent } from '@/utils/event';
import { getJumpUrl } from '@/utils/route';
import { postSubscribe, subscribeMessage } from '@/utils/subscribe';
import Toast from '@/utils/toast';
import { getUserId, getUserInfo, requestUserInfo } from '@/utils/user';

export const sortVideos = (videos: MaterialVideoInfo[]) => {
  return [...videos].sort((a, b) => {
    const num1 = Number(!a.isDefault);
    const num2 = Number(!b.isDefault);
    return num1 - num2;
  });
};

export const isProfileNotChange = (profile: MaterialProfile, newProfile: Partial<MaterialProfile>) => {
  return Object.keys(newProfile).every(key => newProfile[key] === profile[key]);
};

const updateUserIfNeed = async () => {
  const user = getUserInfo();
  if (user.isCreateResume) {
    return;
  }
  await requestUserInfo();
};

export const getBasicInfo = (profile: Pick<MaterialProfile, 'age' | 'height' | 'weight' | 'shoeSize' | 'gender'>) => {
  const result: string[] = [];
  if (typeof profile.age !== 'undefined' && profile.age !== null) {
    result.push(`${profile.age}岁`);
  }
  if (typeof profile.height !== 'undefined' && profile.height !== null) {
    result.push(`${profile.height}cm`);
  }
  if (typeof profile.weight !== 'undefined' && profile.weight !== null) {
    result.push(`${profile.weight}kg`);
  }
  if (typeof profile.shoeSize !== 'undefined' && profile.shoeSize !== null) {
    result.push(`${profile.shoeSize}码`);
  }
  result.push(profile.gender === GenderType.MEN ? '男' : '女');
  return result.join('·');
};

export const chooseMedia = async (option: Taro.chooseMedia.Option = {}) => {
  try {
    const result = await Taro.chooseMedia({
      count: 1,
      mediaType: ['mix'],
      sourceType: ['album'],
      ...option,
    });
    return result;
  } catch (e) {
    return null;
  }
};

export const requestVideoList = async () => {
  const profile = await requestProfileDetail();
  return profile?.materialVideoInfoList || [];
};

export const requestProfileDetail = oncePromise(async () => {
  return http.post<MaterialProfile>(API.GET_PROFILE);
});

export const requestReadProfile = async (data: GetReadProfileRequest) => {
  return http.post<MaterialProfile>(API.READ_PROFILE, { data });
};

export const requestProfileShareCode = async (resumeId: string) => {
  return http.post<MaterialProfile>(API.GET_PROFILE_SHARE_CODE, {
    data: { resumeId },
    contentType: 'application/x-www-form-urlencoded',
  });
};

export const requestShareProfile = async (data: GetShareProfileRequest) => {
  return http.post<MaterialProfile>(API.VIEW_SHARE_PROFILE, { data, contentType: 'application/x-www-form-urlencoded' });
};

export const postVideos = async (materialVideoInfos: MaterialVideoInfo[]) => {
  await http.post(API.SAVE_VIDEOS, { data: { materialVideoInfos } });
  updateUserIfNeed();
};

export const postResumeText = async (resumeText: string) => {
  await http.post(API.CREATE_PROFILE, { data: { resumeText } });
  updateUserIfNeed();
};

export const updateProfile = async (profile: Partial<MaterialProfile>) => {
  await http.post(API.UPDATE_PROFILE, { data: profile });
  updateUserIfNeed();
};

export const updateProfileStatus = async (params: Omit<UpdateProfileStatusRequest, 'userId'>) => {
  const data = {
    ...params,
    userId: getUserId(),
  };
  return http.post(API.UPDATE_PROFILE_STATUS, { data, contentType: 'application/x-www-form-urlencoded' });
};

export const subscribeMaterialMessage = async () => {
  try {
    const tempIds = MessageSubscribeIds;
    const result = await subscribeMessage(tempIds);
    const acceptTempIds = tempIds.filter(id => result[id] && result[id] === 'accept');
    postSubscribe(tempIds, acceptTempIds);
    return result;
  } catch (e) {
    console.error('subscribe message fail', e);
  }
};

export const requestAnchorList = async (data: GetAnchorListRequest) => {
  return http.post<GetAnchorListResponse>(API.GET_ANCHOR_LIST, { data });
};

export const getMaterialShareMessage = async (profile?: MaterialProfile | null, needShareCode: boolean = true) => {
  if (!profile) {
    return null;
  }
  try {
    const { id, name = '', workedSecCategoryStr } = profile;
    const shareCode = needShareCode ? await requestProfileShareCode(id) : undefined;
    const title = `${name} ${workedSecCategoryStr ? `播过 ${workedSecCategoryStr}` : ''}`.trim();
    return {
      title,
      path: getJumpUrl(PageUrl.MaterialView, { shareCode, resumeId: id, source: MaterialViewSource.Share }),
    };
  } catch (error: unknown) {
    const e = error as HttpError;
    const msg = RESPONSE_ERROR_INFO[e.errorCode!];
    msg && Toast.info(msg);
    // console.error('fetch share code failed', e.info?.());
    collectEvent(CollectEventName.REQUEST_MATERIAL_SHARE_CODE_FAILED, {
      profileId: profile.id,
      error: e.info?.() || e.message,
    });
    return null;
  }
};
