/*
 * https://github.com/morethanwords/tweb
 * Copyright (C) 2019-2021 Eduard Kuzmenko
 * https://github.com/morethanwords/tweb/blob/master/LICENSE
 */

import getPreviewURLFromBytes from "../helpers/bytes/getPreviewURLFromBytes";
import { renderImageFromUrlPromise } from "../helpers/dom/renderImageFromUrl";
import replaceContent from "../helpers/dom/replaceContent";
import setInnerHTML from "../helpers/dom/setInnerHTML";
import { recordPromise } from "../helpers/recordPromise";
import sequentialDom from "../helpers/sequentialDom";
import { UserProfilePhoto, ChatPhoto } from "../layer";
import type { PeerPhotoSize } from "../lib/appManagers/appAvatarsManager";
import getPeerColorById from "../lib/appManagers/utils/peers/getPeerColorById";
import { NULL_PEER_ID, REPLIES_PEER_ID } from "../lib/mtproto/mtproto_config";
import getAbbreviation from "../lib/richTextProcessor/getAbbreviation";
import rootScope from "../lib/rootScope";
import getPeerInitials from "./wrappers/getPeerInitials";

export async function putAvatar(
  div: HTMLElement, 
  peerId: PeerId, 
  photo: UserProfilePhoto.userProfilePhoto | ChatPhoto.chatPhoto, 
  size: PeerPhotoSize, 
  img = new Image(), 
  onlyThumb = false
) {
  const r = await rootScope.managers.acknowledged.appAvatarsManager.loadAvatar(peerId, photo, size);
  const loadPromise = r.result;
  const cached = r.cached;

  img.classList.add('avatar-photo');

  let renderThumbPromise: Promise<void>;
  let callback: () => void;
  let thumbImage: HTMLImageElement;
  if(cached) {
    // смотри в misc.ts: renderImageFromUrl
    callback = () => {
      replaceContent(div, img);
      div.dataset.color = '';
    };
  } else {
    const animate = rootScope.settings.animationsEnabled;
    if(animate) {
      img.classList.add('fade-in');
    }

    let isFullLoaded = false;
    if(size === 'photo_big') { // let's load small photo first
      const res = await putAvatar(div, peerId, photo, 'photo_small');
      renderThumbPromise = res.loadPromise;
      thumbImage = res.thumbImage;
    } else if(photo.stripped_thumb) {
      thumbImage = new Image();
      div.classList.add('avatar-relative');
      thumbImage.classList.add('avatar-photo', 'avatar-photo-thumbnail');
      const url = getPreviewURLFromBytes(photo.stripped_thumb);
      renderThumbPromise = renderImageFromUrlPromise(thumbImage, url).then(() => {
        if(isFullLoaded) {
          return;
        }

        replaceContent(div, thumbImage);
      });
    }

    callback = () => {
      isFullLoaded = true;

      if(thumbImage) {
        div.append(img);
      } else {
        replaceContent(div, img);
      }

      setTimeout(() => {
        if(div.childElementCount) {
          sequentialDom.mutateElement(img, () => {
            div.dataset.color = '';
            
            if(animate) {
              img.classList.remove('fade-in');
            }

            if(thumbImage) {
              thumbImage.remove();
            }
          });
        }
      }, animate ? 200 : 0);
    };
  }

  const renderPromise = loadPromise
  .then((url) => renderImageFromUrlPromise(img, url, !cached))
  .then(callback);

  await (renderThumbPromise || renderPromise);

  return {
    cached, 
    loadPromise: renderThumbPromise || renderPromise,
    thumbImage
  };
}

function set(
  div: HTMLElement, 
  innerHTML: Parameters<typeof setInnerHTML>[1], 
  color: string, 
  icon: string
) {
  setInnerHTML(div, innerHTML);
  div.dataset.color = color;
  div.classList.remove('tgico-saved', 'tgico-deletedaccount', 'tgico-reply_filled');
  icon && div.classList.add(icon);
}

// peerId === peerId || title
export default async function putPhoto(
  div: HTMLElement, 
  peerId: PeerId, 
  isDialog = false, 
  title = '', 
  onlyThumb = false, 
  isBig?: boolean
) {
  const myId = rootScope.myId;
  
  if(peerId === myId && isDialog) {
    set(div, '', '', 'tgico-saved');
    return;
  }

  const managers = rootScope.managers;
  
  if(peerId !== NULL_PEER_ID && peerId.isUser()) {
    const user = await managers.appUsersManager.getUser(peerId);
    if(user && user.pFlags && user.pFlags.deleted) {
      set(div, '', getPeerColorById(peerId), 'tgico-deletedaccount');
      return;
    }
  }
  
  const size: PeerPhotoSize = isBig ? 'photo_big' : 'photo_small';
  const photo = await managers.appPeersManager.getPeerPhoto(peerId);
  const avatarAvailable = !!photo;
  const avatarRendered = !!div.firstElementChild && !(div.firstElementChild as HTMLElement).classList.contains('emoji');
  if(!avatarAvailable || !avatarRendered || !(await managers.appAvatarsManager.isAvatarCached(peerId, size))) {
    let color = '';
    if(peerId && (peerId !== myId || !isDialog)) {
      color = getPeerColorById(peerId);
    }

    if(peerId === REPLIES_PEER_ID) {
      set(div, '', color, 'tgico-reply_filled');
      return;
    }

    const abbr = await (title ? getAbbreviation(title) : getPeerInitials(peerId, managers));
    set(div, abbr, color, '');
    //return Promise.resolve(true);
  }

  if(avatarAvailable/*  && false */) {
    const promise = putAvatar(div, peerId, photo, size, undefined, onlyThumb);
    recordPromise(promise, 'putAvatar-' + peerId);
    return promise;
  }
}
