import * as React from 'react';
import { callHandler } from 'nejsbridge/dist/bridge.lofter.es';

import {
  PostCardType,
  PostCardConfig,
  PostDetail,
  AllDetail,
  Props,
  State
} from './type';
import {
  Container,
  Bangs,
} from './index.style';
import { rem } from '../style/function.style';
import { fetchPostDetail } from './fetch-post';
import { fetchCollectionDetail } from './fetch-collection';
import { fetchPushCollectionDetail } from './fetch-push-collection';
import { fetchPostPermaLinksDetail } from './fetch-permalinks-post'
import {
  LofterPostColumnCard
} from './post/ColumnCard';
import {
  LofterPostRowCard
} from './post/RowCard';
import {
  LofterPostTextRowCard
} from './post/TextRowCard';
import {
  LofterSelectedRowCard
} from './post/SelectedCard';
import {
  LofterSelectedColCard
} from './post/SelectedColCard'
import { BaseComponent } from '../base-component'

import { checkIsMp } from '../utils/detect'
import { formatPostUrlToMpPreviewUrl } from '../utils/format'

const CardMap = {
  1: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => (
    <LofterPostColumnCard
      key={`${index}-${postCardConfig.postId}`}
      post={postDetail}
      postCardConfig={postCardConfig}
    />
  ),
  2: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => (
    <LofterPostColumnCard
      key={`${index}-${postCardConfig.postId}`}
      postCardConfig={postCardConfig}
      post={postDetail}
      showAuthor
      showLike
    />
  ),
  3: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => (
    <LofterPostColumnCard
      key={`${index}-${postCardConfig.postId}`}
      postCardConfig={postCardConfig}
      post={postDetail}
      size={2}
      showLike
    />
  ),
  4: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => (
    <LofterPostRowCard
      key={`${index}-${postCardConfig.postId}`}
      postCardConfig={postCardConfig}
      post={postDetail}
      showCover
    />
  ),
  5: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => (
    <LofterPostRowCard
      key={`${index}-${postCardConfig.postId}`}
      postCardConfig={postCardConfig}
      post={postDetail}
      coverType={2}
      showCover
    />
  ),
  6: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail) => (
    <LofterPostTextRowCard
      key={`${index}-${postCardConfig.postId}`}
      postCardConfig={postCardConfig}
      post={postDetail}
    />
  ),
  7: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail, isEdit?: boolean | undefined, rightWidth?: number, useWithoutPrivacy?: boolean) => (
    <LofterSelectedRowCard
      key={`${index}-${postCardConfig.postId}`}
      postCardConfig={postCardConfig}
      post={postDetail}
      isEdit={isEdit}
      useWithoutPrivacy={useWithoutPrivacy}
    // rightWidth={rightWidth}
    />
  ),
  8: (postCardConfig: PostCardConfig, index: number, postDetail?: false | AllDetail, isEdit?: boolean | undefined) => (
    <LofterSelectedColCard
      key={`${index}-${postCardConfig.postId}`}
      postCardConfig={postCardConfig}
      post={postDetail}
      isEdit={isEdit}
    />
  ),
}

const fetchDetailMap = {
  1: fetchPostDetail,
  2: fetchCollectionDetail,
  4: fetchPushCollectionDetail, // type 4 新增的推集类型
  5: fetchPostPermaLinksDetail, // type 5 文章类型新
}

export class LofterPost extends React.Component<Props, State> {
  static defaultProps = new Props();
  state = new State();

  willUpdateNextLoop = false;

  postsDetail: {
    [postId: number]: false | AllDetail
  } = {};

  postsFetching: {
    [postId: number]: boolean
  } = {};

  private unmounted = false;

  componentWillUnmount() {
    this.unmounted = true;
  }
  componentDidMount() {
    this.refresh();
    // 20220920，719版本隐私合规需求
    const { useWithoutPrivacy, isEdit } = this.props;
    console.log('useWithoutPrivacy', useWithoutPrivacy);
    if (useWithoutPrivacy && !isEdit) {
      callHandler('hideActionMenu');
      const bar = document.createElement('div');
      bar.innerText = `解锁更多个性化推荐与功能`
      bar.style.cssText = `
        height: ${rem(64)};
        width: ${rem(718)};
        box-sizing: border-box;
        padding: 0 ${rem(24)};
        margin: 0 auto ${rem(16)};
        border-radius: ${rem(16)};
        background: #f5f5f5;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: ${rem(22)};
        font-weight: 500;
        color: #2E2E2E;
      `
      const action = document.createElement('span');
      action.innerText = '进入完整功能模式';
      action.style.cssText = `
        margin-left: auto;
        box-sizing: border-box;
        padding: ${rem(7)} ${rem(16)};
        font-size: ${rem(24)};
        border-radius: ${rem(24)};
        border: 1px solid #2E2E2E;
        display: flex;
        justify-content: center;
        align-items: center;
      `
      bar.appendChild(action);
      bar.addEventListener('click', () => {
        callHandler('njb_unlock_more');
      })
      const app = document.querySelector('#app');
      document.body.insertBefore(bar, app)
    }
  }

  componentDidUpdate(prevProps: any) {
    if (
      prevProps.posts !== this.props.posts
      && !this.unmounted
    ) {
      this.refresh();
    }
  }

  refresh() {
    if (this.unmounted) return;
    const {
      posts,
      style: oriStyle,
    } = this.props;
    posts.forEach((postCardConfig) => {
      const {
        postId,
        // 此type值为处理type为空情况时请求的map类型，勿改
        type = 1,
      } = postCardConfig;
      // 此处为了尽量复用已有的文章类型支持，只从type扩展
      // 1为文章，2为扩展的合集，4为推集,3为其他类型（自由配置），数据类型尽量保持和文章一致
      // type=3时不做请求，直接mock假数据，全部交由运营配置
      // 这里ts 提示是因为之前是文章类型，后来增加了合集类型，合集类型缺失一些文章类型的属性，后来又增加了推集
      if (postId && type === 3) {
        this.postsDetail[postId] = {
          id: postId,
          // originType: 'other',
          classifyType: 3,
          title: '',
          digest: '',
          postPageUrl: ''
        }
        return;
      }
      if (
        !postId
        || this.postsFetching[postId]
        || typeof this.postsDetail[postId] !== 'undefined'
      ) {
        return;
      }
      this.postsFetching[postId] = true;
      fetchDetailMap[type](postId)
        .then((postDetail: AllDetail) => {
          // if (this.destroyed) return;
          // console.log('postDetail', postDetail)
          if (postDetail) {
            // 增加小程序内单日志展示链接处理
            if (checkIsMp() && postDetail.postPageUrl) {
              postDetail.postPageUrl = formatPostUrlToMpPreviewUrl(postDetail.postPageUrl)
            }
            this.postsDetail[postId] = postDetail;
          } else {
            this.postsDetail[postId] = false;
          }
          this.updateNextLoop()
        });
    })
  }


  updateNextLoop() {
    if (this.willUpdateNextLoop) return;
    this.willUpdateNextLoop = true;
    setTimeout(() => {
      // if (this.destroyed) return;
      this.forceUpdate();
      this.willUpdateNextLoop = false;
    }, 0)
  }

  renderPost(
    type: PostCardType,
    postCardConfig: PostCardConfig,
    index: number,
    isEdit?: boolean | undefined,
    rightWidth?: number,
    useWithoutPrivacy?: boolean,
  ) {

    if (
      CardMap[type]
    ) {
      const postId = postCardConfig.postId;
      const postDetail = this.postsDetail[postId];
      if (
        (postDetail === false || !postId)
        && !this.props.isEdit
      ) return;
      return CardMap[type](
        postCardConfig,
        index,
        postDetail,
        isEdit,
        rightWidth,
        useWithoutPrivacy,
      );
    }
  }

  public render() {
    const {
      style,
      type,
      posts,
      marginTop,
      isEdit,
      rightWidth,
      selectedNegativeMargin,
      useWithoutPrivacy,
    } = this.props;
    // 是否为精选样式
    const isSelected = type === 7; //只有精选样式水平才有上面的推荐语
    return (
      <BaseComponent {...this.props} customStyle={{ position: 'relative', overflow: 'hidden', }}>
        {
          isSelected && selectedNegativeMargin && <Bangs />
        }
        <Container style={{
          ...style,
          marginTop: `${marginTop}rem`
        }}
          type={type}
          isEdit={isEdit}
        >
          {
            posts && posts.map((post, index) => this.renderPost(
              type,
              post,
              index,
              isEdit,
              rightWidth,
              useWithoutPrivacy,
            ))
          }
        </Container>
      </BaseComponent>
    )
  }
}