<template>
  <!--
    问诊助手通用壳：协议抽屉、消息流、选项按钮等。
    仅 follow-up / transfer 分包页使用，放在 subPackages/common 以减小主包体积。
  -->
  <view class="consultation-container safe-area-inset-bottom">
    <view class="consultation-header">
      <view class="header-back" @click="handleHeaderBack">
        <text class="iconfont icon-arrow-left"></text>
      </view>
      <view class="header-title">{{ headerTitle }}</view>
      <view class="header-placeholder"></view>
    </view>

    <view class="notice-box" v-if="showNotice">
      <view class="notice-text">
        <text v-for="(part, index) in parsedNoticeParts" :key="index">
          <text v-if="part.type === 'text'">{{ part.text }}</text>
          <text v-else-if="part.type === 'agreement'" class="notice-link" @click="$emit('viewAgreement', part.agreementId)">
            《{{ part.text }}》
          </text>
        </text>
      </view>
    </view>

    <!-- 协议抽屉：v-if 控制挂载，:show 控制显隐（与 chat 页一致） -->
    <page-container
      v-if="agreementPopupVisible"
      :show="agreementPopupVisible"
      position="bottom"
      round
      overlay
      custom-style="height:88%;"
      @clickoverlay="closeAgreement"
      @afterleave="closeAgreement"
    >
      <view class="agreement-popup">
        <view class="agreement-header">
          <text class="agreement-title">{{ currentAgreementName || '协议详情' }}</text>
          <view class="agreement-close" @click="closeAgreement">×</view>
        </view>
        <scroll-view scroll-y class="agreement-content" :show-scrollbar="true">
          <u-parse :html="agreementContent"></u-parse>
        </scroll-view>
      </view>
    </page-container>

    <scroll-view class="messages-scroll" scroll-y="true" :scroll-into-view="scrollIntoView" scroll-with-animation>
      <view class="messages-container">
        <view v-for="message in displayedMessages" :key="message.id">
          <view v-if="message.type === 'welcome'" class="message-item other">
            <image class="avatar" :src="assistantAvatar" mode="aspectFill"></image>
            <view class="message-content">
              <view class="assistant-label">{{ assistantName }}</view>
              <view class="message-bubble">
                <text>您好! 我是医生助理, 已收到您的用药申请:「{{ prescriptionInfo }}」, 为了帮助医生判断准确, 请按照您的真实情况回答以下问题。</text>
              </view>
            </view>
          </view>

          <view v-else-if="message.type === 'question'" class="message-item other" :id="'question-' + message.questionId">
            <image class="avatar" :src="assistantAvatar" mode="aspectFill"></image>
            <view class="message-content">
              <view class="assistant-label">{{ assistantName }}</view>
              <view class="message-bubble">
                <text>{{ message.content }}</text>
              </view>
            </view>
          </view>

          <view v-else-if="message.type === 'answer'" class="message-item mine">
            <image class="avatar" :src="userAvatar" mode="aspectFill"></image>
            <view class="message-content">
              <view class="message-bubble">
                <text>{{ message.content }}</text>
              </view>
            </view>
          </view>

          <view v-else-if="message.type === 'waiting'" class="message-item other">
            <image class="avatar" :src="assistantAvatar" mode="aspectFill"></image>
            <view class="message-content">
              <view class="assistant-label">{{ assistantName }}</view>
              <view class="message-bubble">
                <text>请稍等, 正在为您转接医生进行复诊开方...</text>
              </view>
            </view>
          </view>

          <view v-else-if="message.type === 'hint'" class="message-item other">
            <image class="avatar" :src="assistantAvatar" mode="aspectFill"></image>
            <view class="message-content">
              <view class="assistant-label">{{ assistantName }}</view>
              <view class="message-bubble">
                <text>{{ message.content }}</text>
              </view>
            </view>
          </view>
        </view>

        <view v-if="isTyping" class="message-item other typing-indicator">
          <image class="avatar" :src="assistantAvatar" mode="aspectFill"></image>
          <view class="message-content">
            <view class="assistant-label">{{ assistantName }}</view>
            <view class="message-bubble typing-bubble">
              <view class="typing-dots">
                <view class="dot"></view>
                <view class="dot"></view>
                <view class="dot"></view>
              </view>
            </view>
          </view>
        </view>

        <view :id="bottomAnchorId" style="height: 1px;"></view>
      </view>
    </scroll-view>

    <slot v-if="customFooterActive && $slots.footer" name="footer"></slot>
    <view
      v-else-if="showQuestionButtons && currentQuestion && !isSubmitting && !showWaiting && answerMode === 'multi'"
      class="action-footer multi-footer safe-area-inset-bottom"
    >
      <!-- 多选适用症：点选 toggling，确认后再提交；选「其他」可填自定义症状 -->
      <view class="multi-options">
        <button
          v-for="(answer, index) in currentQuestionAnswers"
          :key="index"
          hover-class="none"
          :class="['multi-option-btn', { selected: !!multiSelectedFlag[index] }]"
          @click="toggleMultiAnswer(index)"
        >
          {{ answer }}
        </button>
      </view>
      <input
        v-if="multiHasOtherSelected"
        class="multi-other-input"
        v-model="multiOtherText"
        placeholder="请填写具体症状"
        :maxlength="100"
      />
      <!-- 不用原生 disabled，避免微信小程序卡死无法点击；未达标时 toast -->
      <button
        class="action-btn yes-btn confirm-btn"
        hover-class="none"
        :class="{ disabled: !multiConfirmEnabled }"
        @click="confirmMultiAnswer"
      >
        确认
      </button>
    </view>
    <view
      v-else-if="showQuestionButtons && currentQuestion && !isSubmitting && !showWaiting"
      class="action-footer safe-area-inset-bottom"
    >
      <button
        v-for="(answer, index) in currentQuestionAnswers"
        :key="index"
        hover-class="none"
        :class="['action-btn', answerButtonClass(answer, index)]"
        @click="emitSingleAnswer(answer)"
      >
        {{ answer }}
      </button>
    </view>

    <view class="submitting-overlay" v-if="isSubmitting">
      <view class="submitting-content">
        <view class="loading-spinner"></view>
        <text class="submitting-text">{{ submittingText }}</text>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'AssistantConsultationShell',
  props: {
    headerTitle: {
      type: String,
      default: '转诊咨询',
    },
    showNotice: {
      type: Boolean,
      default: true,
    },
    parsedNoticeParts: {
      type: Array,
      default: () => [],
    },
    showAgreement: {
      type: Boolean,
      default: false,
    },
    agreementContent: {
      type: String,
      default: '',
    },
    currentAgreementName: {
      type: String,
      default: '',
    },
    displayedMessages: {
      type: Array,
      default: () => [],
    },
    assistantAvatar: {
      type: String,
      default: 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/images/assistant-avatar.png',
    },
    assistantName: {
      type: String,
      default: '医生助理',
    },
    userAvatar: {
      type: String,
      default: 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk-client-wx/static/images/user-avatar.png',
    },
    prescriptionInfo: {
      type: String,
      default: '',
    },
    isTyping: {
      type: Boolean,
      default: false,
    },
    scrollIntoView: {
      type: String,
      default: '',
    },
    bottomAnchorId: {
      type: String,
      default: 'bottom-anchor',
    },
    /** 为 true 时展示底部「是/否」等选项（与转诊一致） */
    showQuestionButtons: {
      type: Boolean,
      default: true,
    },
    currentQuestion: {
      type: Object,
      default: null,
    },
    currentQuestionAnswers: {
      type: Array,
      default: () => ['是', '否'],
    },
    isSubmitting: {
      type: Boolean,
      default: false,
    },
    showWaiting: {
      type: Boolean,
      default: false,
    },
    submittingText: {
      type: String,
      default: '正在提交...',
    },
    /** 为 true 时使用 #footer 插槽，避免父组件始终占位导致无法显示默认答题按钮 */
    customFooterActive: {
      type: Boolean,
      default: false,
    },
    /**
     * 答题模式：single 点一下即提交；multi 可多选后点确认
     * 诊所复诊按药选适用症用 multi
     */
    answerMode: {
      type: String,
      default: 'single',
    },
  },
  data() {
    return {
      /** 多选已选下标列表（整表替换，微信小程序下比 object+$set 更稳） */
      multiSelectedIndexes: [],
      /** 选「其他」时的自定义症状文案 */
      multiOtherText: '',
      /** 防双击：emit 后立刻锁，题目切换解锁 */
      answeringLock: false,
    };
  },
  watch: {
    // 题目切换时清空多选，避免上一题选中态残留
    currentQuestion() {
      this.multiSelectedIndexes = [];
      this.multiOtherText = '';
      this.answeringLock = false;
    },
    answerMode() {
      this.multiSelectedIndexes = [];
      this.multiOtherText = '';
      this.answeringLock = false;
    },
  },
  computed: {
    agreementPopupVisible: {
      get() {
        return this.showAgreement
      },
      set(val) {
        this.$emit('update:showAgreement', val)
      },
    },
    /** 供模板判断选中，避免 :class 里写 indexOf */
    multiSelectedFlag() {
      const map = {};
      const list = this.multiSelectedIndexes || [];
      for (let i = 0; i < list.length; i++) {
        map[list[i]] = true;
      }
      return map;
    },
    multiSelectedCount() {
      return (this.multiSelectedIndexes || []).length;
    },
    /** 是否选中了「其他」选项 */
    multiHasOtherSelected() {
      const answers = this.currentQuestionAnswers || [];
      const list = this.multiSelectedIndexes || [];
      for (let i = 0; i < list.length; i++) {
        const idx = list[i];
        if (answers[idx] === '其他') {
          return true;
        }
      }
      return false;
    },
    /** 多选确认是否可提交：至少选一项；选了其他则自定义文案非空 */
    multiConfirmEnabled() {
      if (this.multiSelectedCount === 0) return false;
      if (this.multiHasOtherSelected) {
        return !!(this.multiOtherText && String(this.multiOtherText).trim());
      }
      return true;
    },
  },
  methods: {
    handleHeaderBack() {
      if (this.showAgreement) {
        this.closeAgreement();
        return;
      }
      this.$emit('back');
    },
    closeAgreement() {
      this.$emit('update:showAgreement', false);
    },
    answerButtonClass(answer, index) {
      const answers = this.currentQuestionAnswers
      const totalAnswers = answers.length
      if (totalAnswers === 2) {
        if (answer === '是') return 'yes-btn'
        if (answer === '否') return 'no-btn'
      }
      if (index === 0) return 'yes-btn'
      return 'no-btn'
    },
    /** 单选：点一下即提交，防双击重复 emit */
    emitSingleAnswer(answer) {
      if (this.answeringLock || this.isSubmitting) return;
      this.answeringLock = true;
      this.$emit('answer', answer);
    },
    /** 多选：切换某个适用症的选中状态 */
    toggleMultiAnswer(index) {
      if (this.answeringLock || this.isSubmitting) return;
      const list = this.multiSelectedIndexes || [];
      const pos = list.indexOf(index);
      if (pos === -1) {
        this.multiSelectedIndexes = list.concat([index]);
      } else {
        this.multiSelectedIndexes = list.filter((i) => i !== index);
        if (this.currentQuestionAnswers[index] === '其他') {
          this.multiOtherText = '';
        }
      }
    },
    /**
     * 多选确认：选中标签用顿号拼接；「其他」替换为自定义填写内容
     */
    confirmMultiAnswer() {
      if (this.answeringLock || this.isSubmitting) return;
      if (!this.multiConfirmEnabled) {
        if (this.multiSelectedCount === 0) {
          uni.showToast({ title: '请至少选择一项', icon: 'none' });
        } else if (this.multiHasOtherSelected) {
          uni.showToast({ title: '请填写具体症状', icon: 'none' });
        }
        return;
      }
      const indexes = (this.multiSelectedIndexes || []).slice().sort((a, b) => a - b);
      if (!indexes.length) return;
      const otherText = (this.multiOtherText || '').trim();
      const labels = indexes
        .map((i) => {
          const label = this.currentQuestionAnswers[i];
          if (label === '其他') return otherText;
          return label;
        })
        .filter(Boolean);
      if (!labels.length) return;
      this.answeringLock = true;
      this.$emit('answer', labels.join('、'));
      this.multiSelectedIndexes = [];
      this.multiOtherText = '';
    },
  },
}
</script>

<style lang="scss" scoped>
.consultation-container {
  width: 100%;
  height: 100vh;
  background-color: #f8fafc;
  display: flex;
  flex-direction: column;
}

.consultation-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20rpx 30rpx;
  background: #fff;
  border-bottom: 1rpx solid #f0f0f0;
  position: relative;
  flex-shrink: 0;

  .header-back {
    width: 60rpx;
    height: 60rpx;
    display: flex;
    align-items: center;
    justify-content: center;

    .iconfont {
      font-size: 32rpx;
      color: #333;
    }
  }

  .header-title {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    font-size: 32rpx;
    font-weight: 600;
    color: #333;
  }

  .header-placeholder {
    width: 60rpx;
  }
}

.notice-box {
  margin: 20rpx 30rpx;
  padding: 24rpx;
  background: #f5f5f5;
  border-radius: 12rpx;
  font-size: 24rpx;
  line-height: 1.6;
  color: #666;
  flex-shrink: 0;

  .notice-text {
    display: block;
    word-break: break-all;
  }

  .notice-link {
    color: #0a84ff;
    text-decoration: underline;
  }
}

.messages-scroll {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.messages-container {
  padding: 30rpx;
  min-height: 100%;
}

.message-item {
  display: flex;
  align-items: flex-start;
  margin-bottom: 30rpx;

  .avatar {
    width: 72rpx;
    height: 72rpx;
    border-radius: 10rpx;
    flex-shrink: 0;
    background: #f2f2f2;
  }

  .message-content {
    display: flex;
    flex-direction: column;
    max-width: 70%;
    margin-left: 16rpx;

    .assistant-label {
      font-size: 22rpx;
      color: #999;
      margin-bottom: 8rpx;
    }

    .message-bubble {
      padding: 18rpx 24rpx;
      font-size: 30rpx;
      line-height: 1.5;
      border-radius: 4rpx 12rpx 12rpx 12rpx;
      background: #fff;
      color: #333;
      word-break: break-all;
      box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.05);
    }
  }

  &.mine {
    flex-direction: row-reverse;

    .message-content {
      margin-left: 0;
      margin-right: 16rpx;
      align-items: flex-end;

      .message-bubble {
        background: #0a84ff;
        color: #fff;
        border-radius: 12rpx 4rpx 12rpx 12rpx;
      }
    }
  }

  &.typing-indicator {
    .typing-bubble {
      padding: 18rpx 24rpx;
      min-width: 80rpx;
    }

    .typing-dots {
      display: flex;
      align-items: center;
      gap: 8rpx;

      .dot {
        width: 12rpx;
        height: 12rpx;
        border-radius: 50%;
        background: #999;
        animation: typing 1.4s infinite ease-in-out;
      }

      .dot:nth-child(1) {
        animation-delay: 0s;
      }

      .dot:nth-child(2) {
        animation-delay: 0.2s;
      }

      .dot:nth-child(3) {
        animation-delay: 0.4s;
      }
    }
  }
}

@keyframes typing {
  0%,
  60%,
  100% {
    transform: translateY(0);
    opacity: 0.7;
  }
  30% {
    transform: translateY(-10rpx);
    opacity: 1;
  }
}

.action-footer {
  padding: 20rpx 30rpx;
  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
  background: #fff;
  border-top: 1rpx solid #f0f0f0;
  display: flex;
  gap: 20rpx;
  justify-content: space-between;
  flex-shrink: 0;

  .action-btn {
    flex: 1;
    min-height: 88rpx;
    height: auto;
    line-height: 1.35;
    padding: 20rpx 16rpx;
    border-radius: 44rpx;
    font-size: 30rpx;
    font-weight: 500;
    border: none;
    white-space: normal;
    /* 覆盖微信 button 默认白底/按下灰底，避免按钮组背景错乱 */
    background-color: #0a84ff !important;
    color: #fff !important;

    &::after {
      border: none;
    }

    &.yes-btn {
      background-color: #0a84ff !important;
      color: #fff !important;
    }

    &.no-btn {
      background-color: #fff !important;
      color: #333 !important;
      border: 2rpx solid #ddd;
    }

    &.disabled,
    &[disabled] {
      opacity: 0.45;
    }
  }

  &.multi-footer {
    flex-direction: column;
    gap: 16rpx;

    .multi-options {
      display: flex;
      flex-wrap: wrap;
      gap: 16rpx;
    }

    .multi-other-input {
      width: 100%;
      box-sizing: border-box;
      padding: 16rpx 24rpx;
      min-height: 72rpx;
      border-radius: 12rpx;
      background: #f8fafc;
      font-size: 28rpx;
      color: #333;
      border: 1rpx solid #e2e8f0;
    }

    .multi-option-btn {
      min-width: 140rpx;
      padding: 0 28rpx;
      height: 64rpx;
      line-height: 64rpx;
      border-radius: 32rpx;
      font-size: 26rpx;
      background-color: rgba(10, 132, 255, 0.08) !important;
      color: #475569 !important;
      border: 2rpx solid transparent;

      &::after {
        border: none;
      }

      &.selected {
        background-color: #0a84ff !important;
        color: #fff !important;
      }
    }

    .confirm-btn {
      width: 100%;
      flex: none;
      background-color: #0a84ff !important;
      color: #fff !important;
    }
  }
}

.submitting-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;

  .submitting-content {
    background: #fff;
    padding: 60rpx 80rpx;
    border-radius: 16rpx;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 24rpx;

    .loading-spinner {
      width: 60rpx;
      height: 60rpx;
      border: 4rpx solid #f3f3f3;
      border-top: 4rpx solid #0a84ff;
      border-radius: 50%;
      animation: spin 1s linear infinite;
    }

    .submitting-text {
      font-size: 28rpx;
      color: #666;
    }
  }
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.agreement-popup {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #fff;
}

.agreement-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 30rpx 50rpx 20rpx;
  border-bottom: 1rpx solid #e5e7eb;
  background: #fff;
  flex-shrink: 0;
}

.agreement-close {
  width: 48rpx;
  height: 48rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 40rpx;
  color: #64748b;
  line-height: 1;
}

.agreement-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #1e293b;
  line-height: 1.5;
  flex: 1;
  min-width: 0;
}

.agreement-content {
  flex: 1;
  height: 0;
  min-height: 200rpx;
  padding: 30rpx 50rpx 40rpx;
  box-sizing: border-box;
}
</style>
