<template>
  <view :key="layoutKey" :class="pageRootClass" class="tab-page ai-page">
    <view class="ai-list-shell">
      <up-virtual-list
        ref="aiVList"
        class="ai-vlist"
        :list-data="historyList"
        :item-height="slotHeightPx"
        :height="scrollAreaPx"
        :buffer="8"
        key-field="id"
        :scroll-top="vScrollTop"
        @update:scrollTop="vScrollTop = $event"
      >
        <template #default="{ item }">
          <view class="ai-row-cell">
            <view
              class="ai-row"
              :class="{ 'ai-row--hl': highlightId === item.id }"
              role="button"
              :style="{ height: rowBodyPx + 'px' }"
              @click="openSession(item)"
              @longpress.stop="onRowLongPress(item)"
            >
              <view class="ai-row__left">
                <view class="ai-row__icon-circle">
                  <up-icon name="chat" color="#22C55E" :size="22" />
                </view>
              </view>
              <view class="ai-row__right">
                <text class="ai-row__title">{{ item.title }}</text>
                <text class="ai-row__hint">{{ item.preview }}</text>
              </view>
            </view>
          </view>
        </template>
      </up-virtual-list>
    </view>

    <view class="ai-float">
      <view class="ai-float__inner">
        <up-button
          type="primary"
          shape="circle"
          :text="$t('aiPage.createChat')"
          :custom-style="floatBtnStyle"
          @click="createSession"
        />
      </view>
    </view>
  </view>
</template>

<script>
import UButton from 'uview-plus/components/u-button/u-button.vue'
import UIcon from 'uview-plus/components/u-icon/u-icon.vue'
import UVirtualList from 'uview-plus/components/u-virtual-list/u-virtual-list.vue'
import tabPage from '@/mixins/tabPage'
import { ensureApiToken } from '@/utils/apiAuth'
import {
  resolveSessionId,
  normalizeSessionRow,
  sessionTitle,
  DEFAULT_SESSION_TITLE
} from '@/utils/aiConsult'
import {
  listAiConsultSessions,
  createAiConsultSession,
  hideAiConsultSession
} from '@/api/diseaseTreatment/aiOnlineConsult'

const ASSISTANT_PATH = '/package-a/ai-assistant/index'
/** 单行卡片内容区高度（rpx），不含与下一行的间距 */
const ROW_BODY_RPX = 168
/** 列表项之间的间距（rpx），计入虚拟列表单项高度 */
const ROW_GAP_RPX = 20

export default {
  components: {
    'up-button': UButton,
    'up-icon': UIcon,
    'up-virtual-list': UVirtualList
  },
  mixins: [tabPage],
  data() {
    return {
      navTitleKey: 'nav.ai',
      sessions: [],
      listLoading: false,
      rowBodyPx: 76,
      marginPx: 10,
      slotHeightPx: 86,
      scrollAreaPx: 400,
      vScrollTop: 0,
      highlightId: '',
      suppressRowClick: false,
      floatBtnStyle:
        'min-width:280rpx;max-width:92%;height:auto;padding:22rpx 40rpx;display:flex;align-items:center;justify-content:center;'
    }
  },
  computed: {
    historyList() {
      return this.sessions.map((s, idx) => {
        const id = resolveSessionId(s)
        const title =
          sessionTitle(s, this.$t('aiOnlineConsult.defaultSessionTitle')) ||
          this.$t('aiPage.sessionTitle', { n: idx + 1 })
        const preview = (s.lastMessagePreview || '').trim() || this.$t('aiPage.openChat')
        return { id, n: idx + 1, title, preview, raw: s }
      })
    }
  },
  watch: {
    historyList() {
      this.$nextTick(() => {
        this.$refs.aiVList?.measureContainerHeight?.()
      })
    }
  },
  onShow() {
    if (ensureApiToken(false)) {
      this.loadSessions()
    }
  },
  onReady() {
    try {
      this.marginPx = Math.ceil(uni.upx2px(ROW_GAP_RPX))
      this.rowBodyPx = Math.max(64, Math.ceil(uni.upx2px(ROW_BODY_RPX)))
      this.slotHeightPx = this.rowBodyPx + this.marginPx
    } catch (e) {
      this.marginPx = 10
      this.rowBodyPx = 76
      this.slotHeightPx = 86
    }
    this.applyScrollLayoutFallback()
    this.$nextTick(() => this.measureListShell())
  },
  methods: {
    applyScrollLayoutFallback() {
      const sys = uni.getSystemInfoSync()
      const winH = sys.windowHeight || 600
      this.scrollAreaPx = Math.max(200, winH - 30)
    },
    measureListShell() {
      uni.createSelectorQuery()
        .in(this)
        .select('.ai-list-shell')
        .boundingClientRect((rect) => {
          if (rect && rect.height > 0) {
            this.scrollAreaPx = Math.max(200, Math.floor(rect.height))
            this.$nextTick(() => {
              this.$refs.aiVList?.measureContainerHeight?.()
            })
          }
        })
        .exec()
    },
    loadSessions() {
      if (!ensureApiToken()) return
      this.listLoading = true
      listAiConsultSessions({
        pageNum: 1,
        pageSize: 100
      })
        .then((res) => {
          this.sessions = (res.rows || []).map((row) => normalizeSessionRow(row))
        })
        .catch(() => {
          this.sessions = []
        })
        .finally(() => {
          this.listLoading = false
        })
    },
    openSession(item) {
      if (this.suppressRowClick || !item || !item.id) return
      let url = `${ASSISTANT_PATH}?sessionId=${encodeURIComponent(item.id)}`
      const llm = item.raw && (item.raw.llmSessionId || null)
      if (llm) {
        url += `&llmSessionId=${encodeURIComponent(llm)}`
      }
      uni.navigateTo({ url })
    },
    onRowLongPress(item) {
      this.suppressRowClick = true
      setTimeout(() => {
        this.suppressRowClick = false
      }, 450)
      this.highlightId = item.id
      uni.showActionSheet({
        itemList: [this.$t('messagePage.delete')],
        success: (res) => {
          if (res.tapIndex === 0) {
            this.removeSession(item.id)
          }
          this.highlightId = ''
        },
        fail: () => {
          this.highlightId = ''
        }
      })
    },
    removeSession(id) {
      if (!id || !ensureApiToken()) return
      hideAiConsultSession(id)
        .then(() => {
          this.sessions = this.sessions.filter((s) => resolveSessionId(s) !== id)
          this.highlightId = ''
          this.$nextTick(() => {
            this.$refs.aiVList?.measureContainerHeight?.()
          })
        })
        .catch(() => {})
    },
    createSession() {
      if (!ensureApiToken()) return
      uni.showLoading({ mask: true })
      createAiConsultSession({})
        .then((res) => {
          const data = res.data || {}
          const id = resolveSessionId(data)
          if (!id) return
          const row = normalizeSessionRow({
            ...data,
            id,
            realSessionId: id,
            llmSessionId: null
          })
          const exists = this.sessions.some((s) => resolveSessionId(s) === id)
          if (!exists) {
            this.sessions.unshift(row)
          }
          uni.navigateTo({
            url: `${ASSISTANT_PATH}?sessionId=${encodeURIComponent(id)}&new=1`
          })
        })
        .finally(() => {
          uni.hideLoading()
        })
    }
  }
}
</script>

<style lang="scss" scoped>
@import '@/styles/morandi.scss';
@import '@/styles/tab-page.scss';

.ai-page {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 100%;
  padding: 24rpx 16rpx 0;
  box-sizing: border-box;
  gap: 16rpx;
  background: $morandi-bg-page;
}

.ai-list-shell {
  flex: 1;
  min-height: 0;
  height: 0;
  min-width: 0;
  box-sizing: border-box;
}

.ai-vlist {
  width: 100%;
}

.ai-row-cell {
  height: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

.ai-row {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  min-width: 0;
  overflow: hidden;
  padding: 22rpx 20rpx;
  gap: 20rpx;
  box-sizing: border-box;
  border-radius: 16rpx;
  background: $morandi-bg-card;
  border: 1rpx solid $morandi-border;
  flex-shrink: 0;
}

.ai-row--hl {
  background: $morandi-highlight;
  border-color: $morandi-highlight-border;
}

.ai-row__left {
  flex-shrink: 0;
  padding-top: 4rpx;
}

.ai-row__icon-circle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 88rpx;
  height: 88rpx;
  border-radius: 50%;
  background: rgba(34, 197, 94, 0.12);
}

.ai-row__right {
  display: flex;
  flex: 1;
  min-width: 0;
  width: 0;
  flex-direction: column;
  justify-content: center;
  gap: 8rpx;
  overflow: hidden;
}

.ai-row__title {
  display: block;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  font-size: 32rpx;
  line-height: 1.35;
  font-weight: 600;
  color: $morandi-text;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  word-break: normal;
  overflow-wrap: normal;
  flex-shrink: 0;
}

.ai-row__hint {
  display: block;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  font-size: 24rpx;
  line-height: 1.35;
  color: $morandi-text-muted;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  word-break: normal;
  overflow-wrap: normal;
  flex-shrink: 1;
}

.ai-float {
  position: fixed;
  left: 0;
  right: 0;
  z-index: 200;
  display: flex;
  justify-content: center;
  padding: 0 24rpx;
  bottom: calc(140rpx + env(safe-area-inset-bottom));
  pointer-events: none;
}

.ai-float__inner {
  pointer-events: auto;
}
</style>
