import React, {
  useState,
  useEffect,
  forwardRef,
  useRef,
  useImperativeHandle,
} from "react";
import { View, Text, Image, Input } from "@tarojs/components";
import Taro from "@tarojs/taro";
import dayjs from "dayjs";
import CommentServices from "@/services/commentServices";
import type {
  BaseComment,
  Comment,
  ReplyComment,
} from "@/services/commentServices";
import { useUserInfo } from "@/store/userStore";
import sendImg from "@/static/detail/icon-sendup.svg";
import addComment from "@/static/detail/icon-write.svg";
import emptyComment from "@/static/emptyStatus/comment-empty.png";
import CommonPopup from "../CommonPopup";
import styles from "./index.module.scss";

// const PAGESIZE = 4;
const PAGESIZE = 1000;

function toast(msg) {
  Taro.showToast({ title: msg, icon: "none" });
}

interface CommentInputProps {
  onConfirm?: (
    value: { content: string } & Partial<CommentInputReplyParamsType>
  ) => void;
}

// 2️⃣ 定义通过 ref 暴露出去的方法类型
interface CommentInputRef {
  show: (params?: CommentInputReplyParamsType) => void;
}

interface CommentInputReplyParamsType {
  parent_id: number;
  reply_to_user_id: number;
  nickname: string;
}

const CommentInput = forwardRef<CommentInputRef, CommentInputProps>(function (
  props,
  ref
) {
  const { onConfirm } = props;
  const [visible, setVisible] = useState(false);
  const [value, setValue] = useState("");
  const [params, setParams] = useState<
    CommentInputReplyParamsType | undefined
  >();

  const inputDomRef = useRef(null);

  useImperativeHandle(ref, () => ({
    show: (_params: CommentInputReplyParamsType | undefined) => {
      setVisible(true);
      setTimeout(() => {
        inputDomRef.current && inputDomRef.current?.focus();
      }, 100);
      setParams(_params);
    },
  }));

  function handleSend() {
    if (!value) {
      toast("评论内容不得为空");
      return;
    }
    onConfirm?.({ content: value, ...params });
    onClose();
  }

  function onClose() {
    setVisible(false);
    setValue("");
    inputDomRef.current && inputDomRef.current?.blur();
  }
  return (
    <CommonPopup
      visible={visible}
      showHeader={false}
      hideFooter
      zIndex={1002}
      onClose={onClose}
      style={{ height: "60px!important", minHeight: "unset" }}
      enableDragToClose={false}
    >
      <View className={styles.inputContainer}>
        <View className={styles.inputWrapper}>
          <Input
            ref={inputDomRef}
            className={styles.input}
            value={value}
            onInput={(e) => setValue(e.detail.value)}
            placeholder={
              params?.reply_to_user_id ? `回复 @${params.nickname}` : "写评论"
            }
            focus
            maxlength={100}
          />
        </View>
        <View className={styles.sendIcon} onClick={handleSend}>
          <Image className={styles.sendImage} src={sendImg} />
        </View>
      </View>
    </CommonPopup>
  );
});

function isReplyComment(item: BaseComment<any>): item is ReplyComment {
  return "reply_to_user" in item;
}

function getRelativeDay(time) {
  const theTime = dayjs(time);
  const isThisYear = dayjs().isSame(theTime, "year");
  const diffDay = dayjs().startOf("day").diff(theTime, "day");
  return diffDay <= 3
    ? diffDay >= 1
      ? `${diffDay}天前`
      : theTime.format("HH:mm:ss")
    : theTime.format(isThisYear ? "MM-DD HH:mm:ss" : "YYYY-MM-DD HH:mm:ss");
}

function CommentItem(props: {
  level: number;
  publisher_id: number;
  comment: Comment | ReplyComment;
  loadMore: (c: Comment) => void;
  handleReply: (options: CommentInputReplyParamsType) => void;
  handleDelete: (options: { parent_id: number | null; id: number }) => void;
}) {
  const {
    level,
    publisher_id,
    comment,
    loadMore: handleLoadMore,
    handleReply,
    handleDelete,
  } = props;
  const currentUserInfo = useUserInfo();
  const isGamePublisher = publisher_id === comment.user.id;
  const isCommentPublisher = currentUserInfo.id === comment.user.id;
  return (
    <View className={styles.commentItem} key={comment.id}>
      <View style={{ width: level === 1 ? "36px" : "28px" }}>
        <Image
          className={styles.avatar}
          src={comment.user.avatar_url}
          mode="aspectFill"
          style={
            level === 1
              ? { width: "36px", height: "36px" }
              : { width: "28px", height: "28px" }
          }
        />
      </View>
      <View className={styles.contents}>
        <View className={styles.main}>
          <View className={styles.publisherInfo}>
            <View className={styles.nickname}>
              <Text>{comment.user.nickname}</Text>
            </View>
            {isGamePublisher && (
              <View className={styles.role}>
                <Text>组织者</Text>
              </View>
            )}
          </View>
          <View className={styles.content}>
            <Text className={styles.atPeople}>
              {isReplyComment(comment) && comment.reply_to_user
                ? `@${comment.reply_to_user.nickname} `
                : ""}
            </Text>
            <Text>{comment.content}</Text>
          </View>
          <View className={styles.addons}>
            <View className={styles.time}>
              <Text>{getRelativeDay(comment.create_time)}</Text>
            </View>
            <View className={styles.location}>
              <Text>上海</Text>
            </View>
            <View
              className={styles.reply}
              onClick={() =>
                handleReply({
                  parent_id: comment.parent_id || comment.id,
                  reply_to_user_id: comment.user.id,
                  nickname: comment.user.nickname,
                })
              }
            >
              <Text>回复</Text>
            </View>
            {isGamePublisher || isCommentPublisher}
            <View
              className={styles.delete}
              onClick={() =>
                handleDelete({
                  parent_id: comment.parent_id,
                  id: comment.id,
                })
              }
            >
              <Text>删除</Text>
            </View>
          </View>
        </View>
        {!isReplyComment(comment) &&
          comment.replies.map((item: ReplyComment) => (
            <CommentItem
              key={comment.id}
              publisher_id={publisher_id}
              comment={item}
              level={2}
              loadMore={handleLoadMore}
              handleReply={handleReply}
              handleDelete={handleDelete}
            />
          ))}
        {!isReplyComment(comment) &&
          comment.replies.length !== comment.reply_count && (
            <View
              className={styles.viewMore}
              onClick={() => handleLoadMore(comment)}
            >
              展开更多评论
            </View>
          )}
      </View>
    </View>
  );
}

export default forwardRef(function Comments(
  props: { game_id: number; publisher_id: number },
  ref
) {
  const { game_id, publisher_id } = props;
  const [comments, setComments] = useState<Comment[]>([]);
  const inputRef = useRef<CommentInputRef>(null);

  useEffect(() => {
    getComments(1);
  }, [game_id]);

  useImperativeHandle(ref, () => ({
    addComment: handleReply,
    getCommentCount: () => comments.length,
  }));

  async function getComments(page) {
    if (!game_id) return;
    const res = await CommentServices.getComments({
      page,
      pageSize: PAGESIZE,
      game_id,
    });
    if (res.code === 0) {
      const newComments: Comment[] = res.data.rows;
      setComments((prev) => {
        const res = [...prev];
        res.splice(page * PAGESIZE - 1, newComments.length, ...newComments);
        return res;
      });
    }
  }

  async function getReplies(c: Comment) {
    const { replies, id: comment_id } = c;
    const page = replies.length < PAGESIZE ? 1 : replies.length / PAGESIZE + 1;
    const res = await CommentServices.getReplies({
      comment_id,
      page,
      pageSize: PAGESIZE,
    });
    if (res.code === 0) {
      const newReplies = res.data.rows;
      setComments((prev) => {
        const newComments = [...prev];
        newComments.forEach((item) => {
          if (item.id === comment_id) {
            item.replies.splice(
              page === 1 ? 0 : page * PAGESIZE - 1,
              newReplies.length,
              ...newReplies
            );
            item.reply_count = res.data.count;
          }
        });
        return newComments;
      });
    }
  }

  function handleReply(options?: CommentInputReplyParamsType) {
    inputRef.current?.show(options);
  }

  function onSend({ content, parent_id, reply_to_user_id }) {
    if (!parent_id) {
      createComment(content);
      return;
    }
    replyComment({ content, parent_id, reply_to_user_id });
  }

  async function createComment(val: string) {
    const res = await CommentServices.createComment({ game_id, content: val });
    if (res.code === 0) {
      setComments((prev) => {
        return [{ ...res.data, replies: [] }, ...prev];
      });
      toast("发布成功");
    }
  }

  async function replyComment({ parent_id, reply_to_user_id, content }) {
    const res = await CommentServices.replyComment({
      parent_id,
      reply_to_user_id,
      content,
    });
    if (res.code === 0) {
      setComments((prev) => {
        return prev.map((item) => {
          if (item.id === parent_id) {
            return {
              ...item,
              replies: [res.data, ...item.replies],
              reply_count: item.reply_count + 1,
            };
          }
          return item;
        });
      });
      toast("回复成功");
    }
  }

  async function deleteComment({ parent_id, id }) {
    const res = await CommentServices.deleteComment({ comment_id: id });
    if (res.code === 0) {
      if (parent_id) {
        setComments((prev) => {
          return prev.map((item) => {
            if (item.id === parent_id) {
              return {
                ...item,
                replies: item.replies.filter(
                  (replyItem) => replyItem.id !== id
                ),
                reply_count: item.reply_count - 1,
              };
            }
            return item;
          });
        });
      } else {
        setComments((prev) => {
          console.log(prev, parent_id, id);
          return prev.filter((item) => item.id !== id);
        });
      }
      toast("评论已删除");
    }
  }

  return (
    <View className={styles.container}>
      <View className={styles.header}>
        <View className={styles.commentCount}>
          {comments.length > 0 ? `${comments.length} 条` : ""}评论
        </View>
        <View className={styles.addComment} onClick={() => handleReply()}>
          <Image className={styles.addCommentImage} src={addComment} />
          <Text className={styles.addCommentText}>写评论</Text>
        </View>
      </View>
      {comments.length > 0 ? (
        <View className={styles.list}>
          {comments.map((comment) => {
            return (
              <CommentItem
                key={comment.id}
                publisher_id={publisher_id}
                level={1}
                comment={comment}
                loadMore={getReplies}
                handleReply={handleReply}
                handleDelete={deleteComment}
              />
            );
          })}
        </View>
      ) : (
        <View className={styles.empty}>
          <Image className={styles.emptyImage} src={emptyComment} />
          <Text className={styles.emptyTip}>快来发表第一条评论</Text>
        </View>
      )}

      <CommentInput ref={inputRef} onConfirm={onSend} />
    </View>
  );
});
