<script setup lang="jsx">
import { ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { NTabs, NTab, NSelect } from 'naive-ui';
import { useChatStore } from '@/stores/modules/chatStore';
import { BaseTable, ChatWelcome, RecodeSquareCardItem, TheSubMenu, TheChatView } from "@/components";
import { useInfinite, useRecommend, useFetchStream, useScroll } from '@/composables';
import { ChatBaseCard, ChatAnswer } from '@/components/Chat';
import { CustomModal } from "./components";
import { inColumns, outColumns } from './config';

import { formatToData } from "@/utils/format";

import { waterApi } from '@/api/water';

const { recommendList } = useRecommend({ type: 1 });
const { scrollRef, scrollToBottom, scrollToBottomIfAtBottom } = useScroll();
const { refetch, cancelFetch } = useFetchStream("/grpc/decisionStream", { methdos: 'POST' }, false);

const { recordList, isFetching, onScrolltolower, onRestore } = useInfinite('/front/bigModel/warning/pageList', { type: 0, warningStatus: 0 });

const router = useRouter();
const chatStore = useChatStore();

// 回答列表
const answerResult = ref([]);
// 获取最终回答流数据参数
const flowParams = {
  feedback: '',
  category: '',
  warningId: '',
  simulate: '{}'
};

const answerLoading = ref(false);
const textDataSources = ref(null);
const warningActive = ref(0);
const subMenuRef = ref(null);

// 进出水数据
const jsTableData = ref([]);
const csTableData = ref([]);

const visible = ref(false);

const modalData = ref({});

// 菜单水数据类型
const waterTypeValue = ref('');

const options = [
  { label: '全部', value: '' },
  { label: '进水', value: 0 },
  { label: '出水', value: 1 }
]

const mockData = [
  {
    "createBy": "task-job",
    "createTime": "2025-03-05 08:09",
    "updateBy": "task-job",
    "updateTime": "2025-03-05 11:08",
    "remark": "0",
    "id": 4485,
    "type": 0,
    "category": "进水总氮",
    "time": "2025-03-05 10:08",
    "reason": "进水总氮超标报警",
    "warningVal": 71.13,
    "designVal": 65,
    "controlVal": null,
    "forecastVal": null,
    "functionWay": 0,
    "level": "二级",
    "status": 2,
    "isEmergency": 0,
    "offTime": "2025-03-05 11:08:00",
    "operator": null,
    "review": null,
    "useRecommend": null,
    "waterType": 0,
    "symbol": 0,
    "cwrwxz": 1.5385,
    "cwrwfhz": 0.5033,
    "delFlag": 0,
    "revision": 3,
    "counts": "3",
    "warningValStr": null,
    "warningStatus": null,
    "symbolDesc": "超标准值",
    "timeBegin": null,
    "timeEnd": null
  },
  {
  "createBy": "task-job",
  "createTime": "2025-03-04 09:08",
  "updateBy": "task-job",
  "updateTime": "2025-03-05 07:08",
  "remark": null,
  "id": 4469,
  "type": 0,
  "category": "出水氨氮",
  "time": "2025-03-04 09:08",
  "reason": "出水氨氮仪表故障（单指标连续不变）",
  "warningVal": 0.28,
  "designVal": null,
  "controlVal": null,
  "forecastVal": null,
  "functionWay": 0,
  "level": null,
  "status": 2,
  "isEmergency": 0,
  "offTime": "2025-03-05 07:08:56",
  "operator": null,
  "review": null,
  "useRecommend": null,
  "waterType": 1,
  "symbol": 5,
  "cwrwxz": null,
  "cwrwfhz": null,
  "delFlag": 0,
  "revision": 1,
  "counts": "23",
  "warningValStr": null,
  "warningStatus": null,
  "symbolDesc": "仪表故障（单指标连续不变）",
  "timeBegin": null,
  "timeEnd": null
  },
  {
  "createBy": "task-job",
  "createTime": "2025-03-03 02:08",
  "updateBy": "task-job",
  "updateTime": "2025-03-03 04:09",
  "remark": "0",
  "id": 4452,
  "type": 0,
  "category": "进水SS",
  "time": "2025-03-03 03:08",
  "reason": "进水SS超标报警",
  "warningVal": 679.42,
  "designVal": 315,
  "controlVal": null,
  "forecastVal": null,
  "functionWay": 0,
  "level": "一级",
  "status": 2,
  "isEmergency": 0,
  "offTime": "2025-03-03 04:09:44",
  "operator": null,
  "review": null,
  "useRecommend": null,
  "waterType": 0,
  "symbol": 0,
  "cwrwxz": 1.6609,
  "cwrwfhz": 1.2082,
  "delFlag": 0,
  "revision": 2,
  "counts": "3",
  "warningValStr": null,
  "warningStatus": null,
  "symbolDesc": "超标准值",
  "timeBegin": null,
  "timeEnd": null
  }
]
watch(() => waterTypeValue.value, curValue => {
  onRestore({ warningStatus: warningActive.value, waterType: curValue });
})

const handleModelVisible = () => {
  visible.value = true;
}

const resetConfiguration = () => {
  /**
   * 临时这样，后续统一处理
   * */
  textDataSources.value = '';

  answerLoading.value = false;

  answerResult.value = [];

  flowParams.feedback = '';
  flowParams.category = '';
  flowParams.warningId = '';
  flowParams.simulate = '{}';
  cancelFetch();
}

/**
 * 报警详情
*/
const handleOpenContent = async (item) => {
  const { id, category, reason: title, counts } = item;
  if (id == flowParams.warningId) return;


  flowParams.category = category;
  flowParams.warningId = id;
  flowParams.feedback = '';
  flowParams.simulate = '{}';

  answerLoading.value = false;

  answerResult.value = [];

  const { data } = await waterApi.getWaringDetails(id);
  const showVal = JSON.parse(data.showVal);
  const { basic, jsData, csData } = showVal;

  try {
    const answer = JSON.parse(data.answer);
    const reportList = [];
    const alertList = [];
    let simulateObj = null;

    answer.map(item => {
      const answerObjItem = JSON.parse(item);
      switch (answerObjItem.biz) {
        case "DECISION_REPORT":
          reportList.push(answerObjItem.message);
          break
        case "DECISION_ALERT":
          alertList.push(answerObjItem);
          break
        case "DECISION_SIMULATE":
          if (warningActive.value === 1) return;
          const { off, on, pred } = JSON.parse(answerObjItem.message);
          simulateObj = {
            biz: 'DECISION_SIMULATE',
            off,
            on,
            pred,
            isDisable: false
          }
          modalData.value = simulateObj;
      }
    })

    if (reportList.length) {
      answerResult.value.push({
        biz: 'DECISION_REPORT',
        answer: reportList.join(""),
        loading: false,
        delayLoading: false
      })
    }

    if (alertList.length) {
      const [parseAnswer] = alertList.map(item => {
        item.message = Object.keys(item.message).map(key => ({ ...item.message[key], isActive: null }));
        return item;
      })
      answerResult.value.push({
        biz: 'DECISION_ALERT',
        loading: false,
        delayLoading: false,
        isAllSelect: false,
        list: parseAnswer?.message
      })
    }

    if (simulateObj) {
      answerResult.value.push(simulateObj);
    }

  } catch (error) {
    answerResult.value.push({
      biz: 'DECISION_REPORT',
      answer: data.answer,
      loading: false,
      delayLoading: false
    })
  }

  cancelFetch();

  // answerResult.value = [];

  // const reportList = [];
  // const alertList = [];
  // let simulateObj = null;

  // answer.map(item => {
  //   const answerObjItem = JSON.parse(item);
  //   switch(answerObjItem.biz) {
  //     case "DECISION_REPORT":
  //       reportList.push(answerObjItem.message);
  //       break
  //     case "DECISION_ALERT":
  //       alertList.push(answerObjItem);
  //       break
  //     case "DECISION_SIMULATE":
  //       console.log( "DECISION_SIMULATE", answerObjItem.message );
  //       if (warningActive.value === 1) return; 
  //       const { off, on, pred } = JSON.parse(answerObjItem.message);
  //       simulateObj = {
  //         biz: 'DECISION_SIMULATE',
  //         off,
  //         on,
  //         pred,
  //         isDisable: false
  //       }
  //       modalData.value = simulateObj;
  //   }
  // })

  // if ( reportList.length ) {
  //   answerResult.value.push({
  //     biz: 'DECISION_REPORT',
  //     answer: reportList.join(""),
  //     loading: false,
  //     delayLoading: false
  //   })
  // }

  // if ( alertList.length ) {
  //   const [ parseAnswer ] = alertList.map(item => {
  //     item.message = Object.keys(item.message).map(key => ({ ...item.message[key], isActive: null }));
  //     return item;
  //   })
  //   answerResult.value.push({
  //     biz: 'DECISION_ALERT',
  //     loading: false,
  //     delayLoading: false,
  //     isAllSelect: false,
  //     list: parseAnswer?.message
  //   })
  // }

  // if (simulateObj) {
  //   answerResult.value.push(simulateObj);
  // }

  basic.title = title;
  textDataSources.value = formatToData({
    dataSource: basic,
    warnKey: '报警值',
    statusVal: !!warningActive.value ? '系统关闭' : basic['状态']
  });

  jsTableData.value = [jsData];
  csTableData.value = [csData];

}

const onChangeTabs = warningStatus => {
  resetConfiguration();
  warningActive.value = warningStatus;
  onRestore({ warningStatus });
  subMenuRef.value.scrollToTop();
}

// 生成流数据
const onRegenerate = async () => {

  answerLoading.value = true;

  const len = answerResult.value.length ? answerResult.value.length : 0;

  const tempReport = {
    biz: 'DECISION_REPORT',
    answer: '',
    loading: true,
    delayLoading: true,
  };

  let tempSimulate = null;

  answerLoading.value = answerResult.value[len - 1].biz !== 'DECISION_TABLE';

  const feedback = flowParams.feedback

  const params = {
    body: JSON.stringify({ ...flowParams, feedback: JSON.stringify(feedback) }),
    errorHandler: () => { },
    successHandler: data => {

      const item = JSON.parse(data);

      answerLoading.value = false;

      if (item.biz === 'DECISION_REPORT') {
        tempReport.answer += item.message;
        tempReport.delayLoading = false;
        answerResult.value[len] = { ...tempReport };
      }

      if (item.biz === 'DECISION_ALERT') {
        const list = Object.keys(item.message).map(key => ({ ...item.message[key], isActive: null }));
        answerResult.value.push({
          biz: 'DECISION_ALERT',
          loading: true,
          delayLoading: false,
          isAllSelect: false,
          list
        })
      }

      if (item.biz === 'DECISION_SIMULATE') {
        const lastAnswerItem = answerResult.value[len - 1];
        if (lastAnswerItem.biz === 'DECISION_TABLE') {
          answerResult.value[len - 1] = {
            ...lastAnswerItem,
            content: JSON.parse(item.message).pred.join(", ")
          }
        } else {
          const { off, on, pred } = JSON.parse(item.message);
          tempSimulate = {
            biz: 'DECISION_SIMULATE',
            off,
            on,
            pred,
            isDisable: false
          }
          modalData.value = tempSimulate;
        }
      }

      scrollToBottomIfAtBottom();
    }
  }

  try {
    await refetch(params);

    const answerItem = answerResult.value[answerResult.value.length - 1];

    if (answerItem?.biz) {
      answerItem.loading = false;
      answerItem.delayLoading = false;

      if (answerItem.biz === 'DECISION_TABLE') {
        scrollToBottom()
      }
    }

    if (tempSimulate) {
      answerResult.value.push(tempSimulate);
    }

    setTimeout(() => {
      scrollToBottomIfAtBottom();
    }, 500)
  }
  catch (error) {
    console.log("exist error .....", error);
  }
}

// 回答选项点击
const handlerAlertOptions = (item, val, index) => {
  const { list, isAllSelect } = item;

  if (isAllSelect) return;

  val.isActive = index;

  const isExists = list.find(({ isActive }) => isActive === null);

  if (!isExists) {
    item.isAllSelect = true;

    const result = item.list
      .map(({ id, options, isActive }) => ({ [id]: options[isActive] }))
      .reduce((accumulator, currentValue) => {
        Object.keys(currentValue).forEach(key => accumulator[key] = currentValue[key]);
        return accumulator;
      }, {});

    const newResult = { ...flowParams.feedback, ...result };
    flowParams.feedback = newResult;
    onRegenerate();
  }
}

// 开始预测
const handleSendSimulate = ({ simulate, table }) => {
  const len = answerResult.value.length;

  flowParams.simulate = simulate;
  answerResult.value[len - 1].isDisable = true;

  answerResult.value.push({
    biz: 'DECISION_TABLE',
    loading: true,
    delayLoading: false,
    table,
    isDisable: false
  })

  scrollToBottom();

  onRegenerate();
}

// 欢迎页提交
const handleWelcomeRecommend = question => {
  chatStore.setChatQuestion(question);
  router.push('/answer');
}
</script>

<template>
  <section class="flex items-start h-full" id="warning">
    <TheSubMenu title="水质报警" @scrollToLower="onScrolltolower" :loading="isFetching" ref="subMenuRef">
      <template #top>
        <div class="border-[#DAE5ED]">
          <n-tabs type="line" justify-content="space-evenly">
            <n-tab name="oasis" tab="正在报警" @click="onChangeTabs(0)"></n-tab>
            <n-tab name="thebeatles" tab="历史报警" @click="onChangeTabs(1)"></n-tab>
          </n-tabs>
          <div class="select-card">
            <n-select v-model:value="waterTypeValue" :options="options" size="tiny" />
          </div>
        </div>
      </template>

      <div class="px-[12px] py-[14px] text-[#5e5e5e]">
        <p v-show="!recordList.length" class="pt-[30px] text-[12px] text-[#999] text-center">暂无报警数据</p>
        <div class="grid grid-cols-1 gap-[12px]">
          <div v-show="warningActive == 1">
            <RecodeSquareCardItem v-for="item, index in mockData" :key="item.id" :item="item"
              @on-click="handleOpenContent" :style="{ marginBottom: index < 3 ? '10px' : '' }" />
          </div>
          <RecodeSquareCardItem v-for="item in recordList" :key="item.id" :item="item" @on-click="handleOpenContent" />
        </div>
      </div>
    </TheSubMenu>

    <TheChatView ref="scrollRef" :is-footer="false">
      <ChatWelcome title="您好,我是LibraAI生产应急决策" card-title="常见处理方案：" :sub-title="[
        '水质报警功能针对五大核心指标实时监测，发现异常后将推送给相关人员决策方案',
        '报警时间为每小时警报，请大家及时处理'
      ]" :card-content="recommendList" @on-click="handleWelcomeRecommend" v-if="!textDataSources" />
      <ChatBaseCard v-if="textDataSources">
        <div class="waring-answer-wrapper">
          <dl class="message-inner warning-info_medium ">
            <dt class="mb-[2px] font-bold text-[#1A2029]">{{ textDataSources?.title }}</dt>
            <dd v-for="item, index in textDataSources?.list" :key="index">
              <span :class="['message-item', { 'text-[#F44C49]': item.isWarning }]">
                  <span>{{ item.label }}</span>
                  ： 
                  <span class="message-value" :title="item.value">{{ item.value }}</span>
              </span>
            </dd>
          </dl>
          <div class="table-inner">
            <div class="warning-table mb-[8px]">
              <div class="title">
                <span>当前进水数据：</span>
              </div>
              <div class="main">
                <BaseTable :columns="inColumns" :data="jsTableData"></BaseTable>
              </div>
            </div>
            <div class="warning-table">
              <div class="title">
                <span>当前出水数据：</span>
              </div>
              <div class="main">
                <BaseTable :columns="outColumns" :data="csTableData"></BaseTable>
              </div>
            </div>
          </div>
        </div>
      </ChatBaseCard>

      <section v-for="item, index in answerResult" :key="index">
        <template v-if="item.biz === 'DECISION_REPORT'">
          <ChatAnswer :loading="item.loading" :delay-loading="item.delayLoading" :toggleVisibleIcons="false"
            :content="item.answer"></ChatAnswer>
        </template>

        <template v-if="item.biz === 'DECISION_ALERT'">
          <ChatBaseCard :loading="item.loading" :delay-loading="item.delayLoading" :toggleVisibleIcons="false">
            <p class="mb-[15px] font-bold text-[#1A2029]">需要确定以下问题，完成决策方案：</p>
            <ul class="radio-wrapper space-y-[14px]">
              <li class="flex items-center" v-for="val, i in item.list" :key="i">
                <p class="mr-[14px]">{{ val.mainContent }}</p>
                <p class="radio-btn-group space-x-[14px]">
                  <span v-for="option, index in val.options" :class="['radio-btn', { active: val.isActive === index }]"
                    @click="handlerAlertOptions(item, val, index)">{{ option }}</span>
                </p>
              </li>
            </ul>
          </ChatBaseCard>
        </template>

        <template v-if="item.biz === 'DECISION_SIMULATE'">
          <button class="
            px-[30px] py-[10px] mb-[20px]
            rounded-[8px] 
            bg-white text-[13px] 
            text-[#5E5E5E] hover:text-[#2454FF]" :disabled="item.isDisable" @click="handleModelVisible">
            水质预测推演
          </button>
        </template>

        <template v-if="item.biz === 'DECISION_TABLE'">
          <ChatAnswer :loading="item.loading" :delay-loading="item.delayLoading" :toggleVisibleIcons="false"
            class="reset-chart">
            <div class="markdown-body text-[15px] break-all">
              <strong class="block mb-[16px]">推荐指标调整：</strong>
              <div class="custom-table-wrapper">
                <table>
                  <thead>
                    <tr>
                      <th v-for="text in item.table.header" :key="text">{{ text }}</th>
                    </tr>
                  </thead>
                  <tbody class="text-center">
                    <tr>
                      <td v-for="text in item.table.body" :key="text">{{ text }}</td>
                    </tr>
                  </tbody>
                </table>
              </div>
              <strong class="block mb-[16px]">预测推演结果：</strong>
              <span>以上指标达成后，预计{{ flowParams.category }}可达到：{{ item.content }}</span>
            </div>
          </ChatAnswer>
          <button class="
            px-[30px] py-[10px] mb-[20px]
            rounded-[8px]
            bg-white text-[13px]
            text-[#5E5E5E] hover:text-[#2454FF]" :disabled="item.isDisable" @click="handleModelVisible">
            水质预测推演
          </button>
        </template>
      </section>

      <ChatAnswer :loading="answerLoading" :delay-loading="answerLoading" :toggleVisibleIcons="false"
        v-show="answerLoading" loadingText="内容生成中，大概需要1分钟..."></ChatAnswer>

    </TheChatView>
  </section>
  <CustomModal v-model:visible="visible" :current-data="modalData" @on-submit="handleSendSimulate"></CustomModal>
</template>

<style lang="scss">
.reset-chart {
  .markdown-body {
    .custom-table-wrapper {
      width: 100%;
      overflow: hidden;
      padding: 10px;

      table td,
      table th {
        white-space: normal !important;
      }
    }
  }
}

.select-card {
  padding: 15px 10px 0 10px;
}
</style>