<template>
  <el-card class="comment-card">
    <template #header>
      <div class="header">
        <span>评论</span>
        <el-button v-if="canComment" type="primary" size="small" @click="showInput = !showInput">新增</el-button>
      </div>
    </template>
    <ThreadComposer
      v-if="showInput"
      v-model="newComment"
      v-model:file-list="fileList"
      :submitting="loading || uploading"
      :quote-item="quoteComment"
      :member-map="memberMap"
      :user-map="userMap"
      :allow-attachments="true"
      show-cancel
      @submit="submit"
      @cancel="showInput = false"
      @clear-quote="clearQuote"
    />
    <ThreadList
      :items="comments"
      :attachments-map="attachmentsMap"
      :member-map="memberMap"
      :user-map="userMap"
      :can-quote="canComment"
      :can-delete="canDelete"
      @quote="setQuote"
      @delete="remove"
    />
  </el-card>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import type { UploadUserFile } from "element-plus";
import { fetchComments, createComment, deleteComment } from "../api/comments";
import { fetchAttachments, uploadAttachment } from "../api/attachments";
import { useStudyStore } from "../store/study";
import { useAuthStore } from "../store/auth";
import { listMembers } from "../api/members";
import { getMemberDisplayName } from "../utils/display";
import ThreadComposer from "./ThreadComposer.vue";
import ThreadList from "./ThreadList.vue";

interface Props {
  studyId: string;
  entityType: string;
  entityId: string;
  canComment?: boolean;
}

const props = defineProps<Props>();
const comments = ref<any[]>([]);
const loading = ref(false);
const newComment = ref("");
const showInput = ref(false);
const study = useStudyStore();
const auth = useAuthStore();
const members = ref<any[]>([]);
const quoteComment = ref<any | null>(null);
const fileList = ref<UploadUserFile[]>([]);
const attachmentsMap = ref<Record<string, any[]>>({});
const uploading = ref(false);

const load = async () => {
  if (!props.studyId) return;
  loading.value = true;
  try {
    const { data } = await fetchComments(props.studyId, props.entityType, props.entityId);
    comments.value = data.items || data || [];
    await loadAttachments();
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || "评论加载失败");
  } finally {
    loading.value = false;
  }
};

const loadMembers = async () => {
  if (!props.studyId) return;
  try {
    const { data } = await listMembers(props.studyId, { limit: 500 });
    members.value = Array.isArray(data) ? data : data.items || [];
  } catch {
    members.value = [];
  }
};

const memberMap = computed(() =>
  members.value.reduce<Record<string, string>>((acc, cur) => {
    const username = getMemberDisplayName(cur);
    if (cur?.user_id && username) acc[cur.user_id] = username;
    return acc;
  }, {})
);
const userMap = computed(() => {
  const map: Record<string, string> = {};
  if (auth.user?.id) {
    map[auth.user.id] = auth.user.display_name || auth.user.username || auth.user.email || auth.user.id;
  }
  return map;
});

const submit = async () => {
  if (!newComment.value.trim()) {
    ElMessage.warning("请输入评论");
    return;
  }
  if (!study.currentStudy) return;
  loading.value = true;
  try {
    const { data } = await createComment(study.currentStudy.id, props.entityType, props.entityId, {
      content: newComment.value,
      quote_comment_id: quoteComment.value?.id || null,
    });
    const created = data as any;
    if (fileList.value.length && created?.id) {
      uploading.value = true;
      try {
        for (const file of fileList.value) {
          if (!file.raw) continue;
          await uploadAttachment(study.currentStudy.id, "comments", created.id, file.raw as File);
        }
      } finally {
        uploading.value = false;
      }
    }
    ElMessage.success("提交成功");
    newComment.value = "";
    quoteComment.value = null;
    fileList.value = [];
    showInput.value = false;
    load();
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || "提交失败");
  } finally {
    loading.value = false;
  }
};

const setQuote = (comment: any) => {
  quoteComment.value = comment;
  showInput.value = true;
};

const clearQuote = () => {
  quoteComment.value = null;
};

const canDelete = (comment: any) => auth.user?.role === "ADMIN" || comment?.created_by === auth.user?.id;

const remove = async (comment: any) => {
  if (!study.currentStudy || !comment?.id) return;
  const ok = await ElMessageBox.confirm("确认删除该评论？", "提示").catch(() => null);
  if (!ok) return;
  try {
    await deleteComment(study.currentStudy.id, props.entityType, props.entityId, comment.id);
    ElMessage.success("评论已删除");
    load();
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || "删除失败");
  }
};

const loadAttachments = async () => {
  if (!props.studyId || comments.value.length === 0) {
    attachmentsMap.value = {};
    return;
  }
  const entries = await Promise.all(
    comments.value.map(async (c) => {
      try {
        const { data } = await fetchAttachments(props.studyId, "comments", c.id);
        const items = (data as any).items || data || [];
        return [c.id, items] as const;
      } catch {
        return [c.id, []] as const;
      }
    })
  );
  const next: Record<string, any[]> = {};
  entries.forEach(([id, items]) => {
    next[id] = items;
  });
  attachmentsMap.value = next;
};

onMounted(() => {
  loadMembers();
  load();
});
</script>

<style scoped>
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
