<template>
  <!-- 用药工具：顶区 up-tabs；下为三个 Tab 表单与结果区（文案 i18n），白底 -->
  <view :class="pageRootClass" class="tab-page mt-page" :style="pageStyle">
    <scroll-view scroll-y class="mt-scroll" enable-back-to-top :show-scrollbar="false">
      <view class="mt-tabs-wrap">
        <up-tabs
          :current="tabIndex"
          class="mt-tabs"
          :list="tabsList"
          key-name="name"
          :scrollable="false"
          line-color="#22C55E"
          :active-style="{ color: '#15803d', fontWeight: '600' }"
          :inactive-style="{ color: '#78716c' }"
          @update:current="tabIndex = $event"
        />
      </view>

      <!-- 查询药物 -->
      <view v-show="tabIndex === 0" class="mt-panel">
        <view class="mt-row">
          <text class="mt-label text-body">{{ $t('medicineToolsPage.labelDrugName') }}</text>
          <up-search
            v-model="qDrugKeyword"
            class="mt-search"
            shape="round"
            :placeholder="$t('medicineToolsPage.searchDrugPlaceholder')"
            :show-action="false"
            :clearabled="true"
            bg-color="#f5f5f5"
            border-color="#e8e8e8"
          />
        </view>
        <view class="mt-row-btn">
          <up-button
            type="primary"
            shape="circle"
            :text="$t('medicineToolsPage.btnQuery')"
            :loading="queryLoading"
            @click="onQueryDrug"
          />
        </view>
        <view class="mt-gap-lg" />
        <text class="mt-line text-body">{{ $t('medicineToolsPage.labelDrugType') }}：{{ qDisplay.type }}</text>
        <text class="mt-line text-body">{{ $t('medicineToolsPage.labelWithdrawal') }}：{{ qDisplay.withdrawal }}</text>
        <text class="mt-line text-body mt-line--block">{{ $t('medicineToolsPage.labelGuide') }}：{{ qDisplay.guide }}</text>
        <text class="mt-line text-body mt-line--block">{{ $t('medicineToolsPage.labelTaboo') }}：{{ qDisplay.taboo }}</text>
      </view>

      <!-- 计算休药期 -->
      <view v-show="tabIndex === 1" class="mt-panel">
        <view class="mt-row">
          <text class="mt-label text-body">{{ $t('medicineToolsPage.labelDrugName') }}</text>
          <up-search
            v-model="wDrugKeyword"
            class="mt-search"
            shape="round"
            :placeholder="$t('medicineToolsPage.searchDrugPlaceholder')"
            :show-action="false"
            :clearabled="true"
            bg-color="#f5f5f5"
            border-color="#e8e8e8"
          />
        </view>
        <view class="mt-row">
          <text class="mt-label text-body">{{ $t('medicineToolsPage.labelStopDate') }}</text>
          <!-- 只读 picker：不用原生 disabled input，否则小程序上点击无法冒泡到父级，日历弹不出 -->
          <view class="mt-date-field" role="button" @tap.stop="openStopDateCalendar">
            <text
              class="mt-date-field__txt text-body"
              :class="{ 'mt-date-field__txt--placeholder': !stopDateStr }"
            >{{ stopDateStr || $t('medicineToolsPage.pickStopDate') }}</text>
            <up-icon name="arrow-right" color="#78716c" :size="18" />
          </view>
        </view>
        <view class="mt-row-btn">
          <up-button
            type="primary"
            shape="circle"
            :text="$t('medicineToolsPage.btnCalc')"
            :loading="calcLoading"
            @click="onCalcWithdrawal"
          />
        </view>
        <view class="mt-gap-lg" />
        <text class="mt-line text-body">{{ $t('medicineToolsPage.labelWithdrawal') }}：{{ wDisplay.withdrawal }}</text>
        <text class="mt-line text-body mt-line--block">{{ $t('medicineToolsPage.labelEndDate') }}：{{ wDisplay.endDate }}</text>
      </view>

      <!-- 用药配伍：默认 2 行，可添加至最多 20 行；至少保留 1 行 -->
      <view v-show="tabIndex === 2" class="mt-panel">
        <view v-for="(row, idx) in compatDrugRows" :key="row.id" class="mt-row mt-row--compat">
          <text class="mt-label text-body">{{ $t('medicineToolsPage.labelDrugNth', { n: idx + 1 }) }}</text>
          <up-search
            v-model="row.keyword"
            class="mt-search"
            shape="round"
            :placeholder="$t('medicineToolsPage.searchDrugPlaceholder')"
            :show-action="false"
            :clearabled="true"
            bg-color="#f5f5f5"
            border-color="#e8e8e8"
          />
          <!-- <view
            v-if="compatDrugRows.length > 2"
            class="mt-compat-remove"
            role="button"
            @tap="removeCompatDrugRow(row.id)"
          >
            <up-icon name="trash" color="#9ca3af" :size="20" />
            <text class="mt-compat-remove__txt text-body">{{ $t('medicineToolsPage.btnRemoveCompatRow') }}</text>
          </view> -->
        </view>
        <!-- <view class="mt-compat-add">
          <up-button
            type="success"
            plain
            hairline
            size="small"
            :text="$t('medicineToolsPage.btnAddCompatDrug')"
            :disabled="compatDrugRows.length >= compatMaxRows"
            @click="addCompatDrugRow"
          />
        </view> -->
        <view class="mt-row-btn">
          <up-button
            type="primary"
            shape="circle"
            :text="$t('medicineToolsPage.btnCompat')"
            :loading="compatLoading"
            @click="onCompat"
          />
        </view>
        <view class="mt-gap-lg" />
        <text class="mt-line text-body">{{ $t('medicineToolsPage.labelForbidden') }}：{{ cDisplay.forbidden }}</text>
        <text class="mt-line text-body mt-line--block">{{ $t('medicineToolsPage.labelCompatResult') }}：{{ cDisplay.result }}</text>
      </view>

      <view class="mt-footer-spacer" />
    </scroll-view>

    <up-calendar
      :key="calendarRenderKey"
      :show="calendarShow"
      mode="single"
      :month-switch="true"
      :min-date="calendarMinDate"
      :max-date="calendarMaxDate"
      :default-date="calendarDefaultDate"
      :month-num="calendarMonthNum"
      color="#22C55E"
      :round="16"
      :close-on-click-overlay="true"
      :title="$t('medicineToolsPage.calendarTitle')"
      :confirm-text="$t('medicineToolsPage.calendarConfirm')"
      @close="calendarShow = false"
      @confirm="onCalendarConfirm"
    />
  </view>
</template>

<script>
import USearch from 'uview-plus/components/u-search/u-search.vue'
import UTabs from 'uview-plus/components/u-tabs/u-tabs.vue'
import UButton from 'uview-plus/components/u-button/u-button.vue'
import UIcon from 'uview-plus/components/u-icon/u-icon.vue'
import UCalendar from 'uview-plus/components/u-calendar/u-calendar.vue'
import tabPage from '@/mixins/tabPage'
import pageViewport from '@/mixins/pageViewport'
import { queryDrug, calculateWithdrawal, checkCompatibility } from '@/api/medication'

function todayYmd() {
  const d = new Date()
  const p = (n) => String(n).padStart(2, '0')
  return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`
}

/** 以「当前本地日期」为基准偏移整年，得到 YYYY-MM-DD */
function addYearsFromToday(deltaYears) {
  const t = new Date()
  t.setFullYear(t.getFullYear() + deltaYears)
  const p = (n) => String(n).padStart(2, '0')
  return `${t.getFullYear()}-${p(t.getMonth() + 1)}-${p(t.getDate())}`
}

function normalizeCalendarValue(val) {
  if (val == null) return ''
  if (typeof val === 'string') return val.length >= 10 ? val.slice(0, 10) : val
  if (Array.isArray(val) && val.length) {
    return normalizeCalendarValue(val[0])
  }
  if (typeof val === 'object' && val.date) {
    const d = val.date instanceof Date ? val.date : new Date(val.date)
    if (!Number.isNaN(d.getTime())) {
      const p = (n) => String(n).padStart(2, '0')
      return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`
    }
  }
  return ''
}

/** 与 u-calendar 内 getMonths 一致：起止 YYYY-MM-DD 之间（含首尾月）的月份个数 */
function countMonthsInclusive(minYmd, maxYmd) {
  const p = (s) => {
    const a = (s || '').split('-').map((x) => parseInt(x, 10))
    return { y: a[0], m: a[1] }
  }
  const A = p(minYmd)
  const B = p(maxYmd)
  if (!A.y || !A.m || !B.y || !B.m) return 1
  return (B.y - A.y) * 12 + (B.m - A.m) + 1
}

/** 用药配伍：最多药物行数 */
const COMPAT_MAX_ROWS = 20

export default {
  components: {
    'up-search': USearch,
    'up-tabs': UTabs,
    'up-button': UButton,
    'up-icon': UIcon,
    'up-calendar': UCalendar
  },
  mixins: [tabPage, pageViewport],
  data() {
    return {
      navTitleKey: 'homeGrid.medicineTools',
      tabIndex: 0,
      queryLoading: false,
      calcLoading: false,
      compatLoading: false,
      qDrugKeyword: '',
      qDisplay: { type: '—', withdrawal: '—', guide: '—', taboo: '—' },
      wDrugKeyword: '',
      stopDateStr: '',
      calendarShow: false,
      calendarRenderKey: 0,
      wDisplay: { withdrawal: '—', endDate: '—' },
      compatMaxRows: COMPAT_MAX_ROWS,
      compatDrugUid: 2,
      compatDrugRows: [
        { id: 1, keyword: '' },
        { id: 2, keyword: '' }
      ],
      cDisplay: { forbidden: '—', result: '—' }
    }
  },
  computed: {
    tabsList() {
      return [
        { name: this.$t('medicineToolsPage.tabQuery'), id: 'q' },
        { name: this.$t('medicineToolsPage.tabWithdrawal'), id: 'w' },
        { name: this.$t('medicineToolsPage.tabCompat'), id: 'c' }
      ]
    },
    /** u-calendar 默认 monthNum=3 只会生成 3 个月；设为 min～max 之间的月数才能滚满范围 */
    calendarMonthNum() {
      const n = countMonthsInclusive(this.calendarMinDate, this.calendarMaxDate)
      return Math.min(240, Math.max(1, n))
    },
    calendarMinDate() {
      return addYearsFromToday(-2)
    },
    calendarMaxDate() {
      return addYearsFromToday(2)
    },
    /** 日历打开时默认高亮：已选且在范围内则用已选，否则为今天 */
    calendarDefaultDate() {
      const min = this.calendarMinDate
      const max = this.calendarMaxDate
      const s = (this.stopDateStr || '').trim()
      if (s && s >= min && s <= max) return s
      return todayYmd()
    }
  },
  methods: {
    openStopDateCalendar() {
      this.calendarRenderKey += 1
      this.calendarShow = true
    },
    onCalendarConfirm(val) {
      this.calendarShow = false
      const ymd = normalizeCalendarValue(val)
      if (ymd) this.stopDateStr = ymd
    },
    onQueryDrug() {
      const drugName = (this.qDrugKeyword || '').trim()
      if (!drugName) {
        uni.showToast({ title: this.$t('medicineToolsPage.toastEmptyDrug'), icon: 'none' })
        return
      }
      if (this.queryLoading) return
      this.queryLoading = true
      queryDrug({ drugName })
        .then((res) => {
          const d = res.data || {}
          this.qDisplay = {
            type: d.drugTypeName || '—',
            withdrawal:
              d.withdrawalDays != null
                ? this.$t('medicineToolsPage.daysTpl', { n: d.withdrawalDays })
                : '—',
            guide: d.usageGuide || '—',
            taboo: d.incompatibilityCompanions || '—'
          }
        })
        .catch(() => {
          this.qDisplay = { type: '—', withdrawal: '—', guide: '—', taboo: '—' }
        })
        .finally(() => {
          this.queryLoading = false
        })
    },
    onCalcWithdrawal() {
      const drugName = (this.wDrugKeyword || '').trim()
      if (!drugName) {
        uni.showToast({ title: this.$t('medicineToolsPage.toastEmptyDrug'), icon: 'none' })
        return
      }
      if (!this.stopDateStr) {
        uni.showToast({ title: this.$t('medicineToolsPage.toastPickDate'), icon: 'none' })
        return
      }
      if (this.calcLoading) return
      this.calcLoading = true
      calculateWithdrawal({ drugName, stopDate: this.stopDateStr })
        .then((res) => {
          const d = res.data || {}
          this.wDisplay = {
            withdrawal:
              d.withdrawalDays != null
                ? this.$t('medicineToolsPage.daysTpl', { n: d.withdrawalDays })
                : '—',
            endDate: d.endDate || '—'
          }
        })
        .catch(() => {
          this.wDisplay = { withdrawal: '—', endDate: '—' }
        })
        .finally(() => {
          this.calcLoading = false
        })
    },
    addCompatDrugRow() {
      if (this.compatDrugRows.length >= COMPAT_MAX_ROWS) {
        uni.showToast({ title: this.$t('medicineToolsPage.toastCompatMax', { n: COMPAT_MAX_ROWS }), icon: 'none' })
        return
      }
      this.compatDrugUid += 1
      this.compatDrugRows.push({ id: this.compatDrugUid, keyword: '' })
    },
    removeCompatDrugRow(id) {
      if (this.compatDrugRows.length <= 1) {
        uni.showToast({ title: this.$t('medicineToolsPage.toastCompatMinRows'), icon: 'none' })
        return
      }
      this.compatDrugRows = this.compatDrugRows.filter((r) => r.id !== id)
    },
    onCompat() {
      const rows = this.compatDrugRows
      const drugNames = []
      for (let i = 0; i < rows.length; i++) {
        const raw = (rows[i].keyword || '').trim()
        if (!raw) continue
        drugNames.push(raw)
      }
      if (drugNames.length < 2) {
        this.cDisplay = { forbidden: '—', result: '—' }
        uni.showToast({ title: this.$t('medicineToolsPage.toastCompatNeedTwoResolved'), icon: 'none' })
        return
      }
      if (new Set(drugNames).size !== drugNames.length) {
        this.cDisplay = { forbidden: '—', result: '—' }
        uni.showToast({ title: this.$t('medicineToolsPage.toastCompatDup'), icon: 'none' })
        return
      }
      if (this.compatLoading) return
      this.compatLoading = true
      const pairTasks = []
      for (let i = 0; i < drugNames.length; i++) {
        for (let j = i + 1; j < drugNames.length; j++) {
          pairTasks.push(
            checkCompatibility({ drugName1: drugNames[i], drugName2: drugNames[j] }).then((res) => ({
              a: drugNames[i],
              b: drugNames[j],
              data: res.data || {}
            }))
          )
        }
      }
      Promise.all(pairTasks)
        .then((results) => {
          const badPairs = results.filter((item) => item.data.hasIncompatibility)
          const forbidden = badPairs.length > 0
          const listStr = badPairs
            .map(({ a, b, data }) => {
              const result = (data.compatResult || '').trim()
              return result
                ? this.$t('medicineToolsPage.compatPairResultTpl', { a, b, result })
                : this.$t('medicineToolsPage.compatPairTpl', { a, b })
            })
            .join('；')
          this.cDisplay = {
            forbidden: forbidden
              ? this.$t('medicineToolsPage.forbiddenYes')
              : this.$t('medicineToolsPage.forbiddenNo'),
            result: forbidden
              ? this.$t('medicineToolsPage.compatMultiForbidden', { list: listStr })
              : this.$t('medicineToolsPage.compatMultiSafe')
          }
        })
        .catch(() => {
          this.cDisplay = { forbidden: '—', result: '—' }
        })
        .finally(() => {
          this.compatLoading = false
        })
    }
  }
}
</script>

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

.mt-page {
  display: flex;
  flex-direction: column;
  min-width: 0;
  width: 100%;
  height: 100%;
  min-height: 100%;
  overflow: hidden;
  box-sizing: border-box;
  background: #ffffff;
}

.mt-scroll {
  flex: 1;
  min-height: 0;
  min-width: 0;
  height: 0;
  box-sizing: border-box;
  background: #ffffff;
}

.mt-tabs-wrap {
  padding: 16rpx 24rpx 12rpx;
  box-sizing: border-box;
  background: #ffffff;
  border-bottom: 1rpx solid #f0f0f0;
}

.mt-tabs {
  width: 100%;
  min-width: 0;
}

.mt-panel {
  display: flex;
  flex-direction: column;
  gap: 20rpx;
  min-width: 0;
  padding: 20rpx 24rpx 32rpx;
  box-sizing: border-box;
}

.mt-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 16rpx;
  min-width: 0;
}

.mt-label {
  flex-shrink: 0;
  width: 160rpx;
  color: $morandi-text-secondary;
}

.mt-search {
  flex: 1;
  min-width: 0;
}

.mt-row--compat {
  align-items: stretch;
}

.mt-compat-remove {
  flex-shrink: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 6rpx;
  padding: 0 8rpx;
  min-height: 64rpx;
  box-sizing: border-box;
}

.mt-compat-remove__txt {
  font-size: 22rpx;
  color: #9ca3af;
  line-height: 1.2;
  white-space: nowrap;
}

.mt-compat-add {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  padding-top: 4rpx;
}

.mt-date-field {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 12rpx;
  box-sizing: border-box;
  padding: 10rpx 18rpx;
  min-height: 72rpx;
  border: 1rpx solid #e8e8e8;
  border-radius: 8rpx;
  background: #ffffff;
}

.mt-date-field__txt {
  flex: 1;
  min-width: 0;
  font-size: 28rpx;
  line-height: 1.45;
  color: #303133;
  word-break: break-all;
}

.mt-date-field__txt--placeholder {
  color: #c0c4cc;
}

.mt-row-btn {
  display: flex;
  flex-direction: row;
  justify-content: center;
  padding-top: 8rpx;
}

.mt-row-btn :deep(.u-button) {
  min-width: 280rpx;
}

.mt-gap-lg {
  height: 32rpx;
}

.mt-line {
  color: $morandi-text;
  line-height: 1.55;
  word-break: break-word;
  overflow-wrap: anywhere;
}

.mt-line--block {
  display: block;
}

.mt-footer-spacer {
  height: 48rpx;
}

.mt-page.lang-bo {
  .mt-label {
    width: 200rpx;
    font-size: 24rpx;
    line-height: 1.75;
    letter-spacing: 2rpx;
    font-family: 'Noto Sans Tibetan', 'PingFang SC', 'Microsoft YaHei', sans-serif;
  }

  .mt-line {
    font-size: 26rpx;
    line-height: 1.75;
    letter-spacing: 2rpx;
    font-family: 'Noto Sans Tibetan', 'PingFang SC', 'Microsoft YaHei', sans-serif;
  }

  .mt-date-field__txt {
    font-size: 26rpx;
    line-height: 1.75;
    letter-spacing: 2rpx;
    font-family: 'Noto Sans Tibetan', 'PingFang SC', 'Microsoft YaHei', sans-serif;
  }
}
</style>
