<script setup lang="ts">
import { ElNotification } from 'element-plus'
import { pick } from 'lodash'

import api from '@/api/index.ts'

import SvgIcon from '@/components/SvgIcon/index.vue'
import { agentMapDuty, getActionTypeDisplay, getAgentMapIcon } from '@/layout/components/config.ts'
import { type Agent, useAgentsStore } from '@/stores'
import { onMounted } from 'vue'
import { v4 as uuidv4 } from 'uuid'

const emit = defineEmits<{
  (el: 'resetAgentRepoLine'): void
}>()

const agentsStore = useAgentsStore()

const handleScroll = () => {
  emit('resetAgentRepoLine')
}

onMounted(() => {
  // 如果已上传就重新发送给后端
  if (agentsStore.agents.length) {
    void api.setAgents(agentsStore.agents.map((item) => pick(item, ['Name', 'Profile'])))
  }
})

// 上传agent文件
const fileInput = ref<HTMLInputElement>()

const triggerFileSelect = () => {
  fileInput.value?.click()
}

const handleFileSelect = (event: Event) => {
  const input = event.target as HTMLInputElement
  if (input.files && input.files[0]) {
    const file = input.files[0]
    readFileContent(file)
  }
}

const readFileContent = async (file: File) => {
  const reader = new FileReader()
  reader.onload = async (e) => {
    if (!e.target?.result) {
      return
    }
    try {
      const json = JSON.parse(e.target.result?.toString?.() ?? '{}')
      // 处理 JSON 数据
      if (Array.isArray(json)) {
        const isValid = json.every(
          (item) =>
            typeof item.Name === 'string' &&
            typeof item.Icon === 'string' &&
            typeof item.Profile === 'string',
        )
        if (isValid) {
          // 处理有效的 JSON 数据
          agentsStore.setAgents(
            json.map((item) => ({
              Name: item.Name,
              Icon: item.Icon.replace(/\.png$/, ''),
              Profile: item.Profile,
            })),
          )
          await api.setAgents(json.map((item) => pick(item, ['Name', 'Profile'])))
        } else {
          ElNotification.error({
            title: '错误',
            message: 'JSON 格式错误',
          })
        }
      } else {
        console.error('JSON is not an array')
        ElNotification.error({
          title: '错误',
          message: 'JSON 格式错误',
        })
      }
    } catch (e) {
      console.error(e)
    }
  }
  reader.readAsText(file)
}

const taskProcess = computed(() => {
  const list = agentsStore.currentTask?.TaskProcess ?? []
  return list.map((item) => ({
    ...item,
    key: uuidv4(),
  }))
})

const agentListRef = ref<HTMLElement | null>()

// 根据currentTask排序agent列表
const agentList = computed(() => {
  const startArr: Agent[] = []
  const endArr: Agent[] = []
  if (!agentsStore.agents.length) {
    return startArr
  }
  for (const agent of agentsStore.agents) {
    if (agentsStore.currentTask?.AgentSelection?.includes(agent.Name)) {
      startArr.push(agent)
    } else {
      endArr.push(agent)
    }
  }

  return [...startArr, ...endArr]
})
</script>

<template>
  <div class="agent-repo h-full flex flex-col" id="agent-repo">
    <!-- 头部 -->
    <div class="flex items-center justify-between">
      <span class="text-[18px] font-bold">智能体库</span>
      <!-- 上传文件 -->
      <input type="file" accept=".json" @change="handleFileSelect" class="hidden" ref="fileInput" />
      <div class="plus-button" @click="triggerFileSelect">
        <svg-icon icon-class="plus" color="var(--color-text)" size="18px" />
      </div>
    </div>
    <!-- 智能体列表 -->
    <div
      class="mt-[18px] flex-1 overflow-y-auto relative"
      ref="agentListRef"
      @scroll="handleScroll"
    >
      <el-popover
        v-for="item in agentList"
        :key="item.Name"
        trigger="hover"
        placement="bottom"
        :show-arrow="false"
        :disabled="!agentsStore.currentTask?.AgentSelection?.includes(item.Name)"
        popper-class="agent-repo-item-popover active-card"
        :append-to="agentListRef"
        width="100%"
      >
        <template #reference>
          <div
            class="flex items-center justify-between user-item relative h-[41px]"
            :class="
              agentsStore.currentTask?.AgentSelection?.includes(item.Name) ? 'active-card' : ''
            "
          >
            <div
              class="w-[41px] h-[41px] rounded-full flex items-center justify-center flex-shrink-0"
              :style="{ background: getAgentMapIcon(item.Name).color }"
            >
              <svg-icon
                :icon-class="getAgentMapIcon(item.Name).icon"
                color="var(--color-text)"
                size="24px"
              />
            </div>
            <div class="flex-1 text-[14px] flex flex-col items-end justify-end truncate ml-1">
              <span
                class="w-full truncate text-right"
                :style="
                  agentsStore.currentTask?.AgentSelection?.includes(item.Name)
                    ? 'color:#00F3FF'
                    : ''
                "
                >{{ item.Name }}</span
              >
              <div
                v-if="agentsStore.currentTask?.AgentSelection?.includes(item.Name)"
                class="flex items-center gap-[7px] h-[8px] mr-1"
              >
                <!-- 小圆点 -->
                <div
                  v-for="item1 in taskProcess.filter((i) => i.AgentName === item.Name)"
                  :key="item1.key"
                  class="w-[6px] h-[6px] rounded-full"
                  :style="{ background: getActionTypeDisplay(item1.ActionType)?.color }"
                ></div>
              </div>
            </div>
          </div>
        </template>
        <div>
          <div class="flex items-center justify-between">
            <div
              class="w-[41px] h-[41px] rounded-full flex items-center justify-center flex-shrink-0 relative right-[2px] bottom-[2px] self-start"
              :style="{ background: getAgentMapIcon(item.Name).color }"
            >
              <svg-icon
                :icon-class="getAgentMapIcon(item.Name).icon"
                color="var(--color-text)"
                size="24px"
              />
            </div>
            <div
              class="flex-1 text-[14px] flex flex-col items-center justify-center break-all ml-1 text-[14px] text-[#00F3FF] p-[8px] pl-[0]"
            >
              {{ item.Name }}
            </div>
          </div>
          <div class="w-full flex justify-center">
            <div
              class="rounded-[9px] bg-[var(--color-bg-quaternary)] text-[12px] py-0.5 px-5 text-center my-2"
            >
              当前指责
            </div>
          </div>
          <div class="p-[8px] pt-0">
            <div
              v-for="(item1, index1) in taskProcess.filter((i) => i.AgentName === item.Name)"
              :key="item1.key"
              class="text-[12px]"
            >
            <div>
              <div class="mx-1 inline-block h-[14px]">
                <div
                  :style="{ background: getActionTypeDisplay(item1.ActionType)?.color }"
                  class="w-[6px] h-[6px] rounded-full mt-[7px]"
                ></div>
              </div>
              <span :style="{ color: getActionTypeDisplay(item1.ActionType)?.color }">{{ getActionTypeDisplay(item1.ActionType)?.name }}：</span>
              <span>{{  item1.Description }}</span>
            </div>
              <!-- 分割线 -->
              <div v-if="index1 !== taskProcess.filter((i) => i.AgentName === item.Name).length - 1" class="h-[1px] w-full bg-[#494B51] my-[8px]"></div>
            </div>
          </div>
        </div>
      </el-popover>
    </div>
    <!-- 底部提示栏 -->
    <div class="w-full grid grid-cols-3 gap-x-[10px] bg-[#1d222b] rounded-[20px] p-[8px] mt-[10px]">
      <div
        v-for="item in Object.values(agentMapDuty)"
        :key="item.key"
        class="flex items-center justify-center gap-x-1"
      >
        <span class="text-[12px]">{{ item.name }}</span>
        <div class="w-[8px] h-[8px] rounded-full" :style="{ background: item.color }"></div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.agent-repo {
  padding: 0 8px;

  .plus-button {
    background: #1d2128;
    width: 24px;
    height: 24px;
    padding: 0;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.3s ease;

    &:hover {
      background: #374151;
      box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
    }
  }

  .user-item {
    background: #1d222b;
    border-radius: 40px;
    padding-right: 12px;
    cursor: pointer;
    transition: all 0.25s ease;
    color: #969696;

    & + .user-item {
      margin-top: 8px;
    }

    &:hover {
      box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
      color: #b8b8b8;
    }
  }

  .active-card {
    border-left: none !important;
  }
}

#agent-repo {
  :deep(.agent-repo-item-popover) {
    padding: 0;
    border-radius: 20px;
    background: var(--color-bg-secondary);
  }
}
</style>
