<template>
  <!-- 培训详情：上懒加载图；中白底信息；下白底仅展示一个 up-button（随状态切换） -->
  <view :class="pageRootClass" class="tab-page td-page">
    <scroll-view scroll-y class="td-scroll" enable-back-to-top>
      <view class="td-inner">
        <view class="td-top">
          <up-lazy-load
            class="td-cover"
            :image="coverSrc"
            height="360"
            :border-radius="16"
            img-mode="aspectFill"
            :threshold="120"
            :index="courseId || 'td'"
            @click="onPreviewCover"
          />
        </view>

        <view class="td-panel td-panel--info">
          <text class="td-title">{{ displayTitle }}</text>
          <text class="text-body td-line">{{ $t('trainingDetailPage.labelRegisterTime') }}：{{ registerRange }}</text>
          <text class="text-body td-line">{{ $t('trainingDetailPage.labelEnrolled') }}：{{ enrolledDisplay }}</text>
          <text class="text-body td-line">{{ $t('trainingDetailPage.labelPlace') }}：{{ placeText }}</text>
          <text class="text-body td-line td-line--block">{{ $t('trainingDetailPage.labelIntro') }}：{{ introText }}</text>
          <text class="text-body td-line td-line--block">{{ $t('trainingDetailPage.labelOutcome') }}：{{ outcomeText }}</text>
        </view>

        <view class="td-panel td-panel--actions">
          <up-button
            class="td-btn"
            :type="actionBtn.buttonType"
            :plain="actionBtn.plain"
            :hairline="actionBtn.hairline"
            :text="actionBtn.text"
            :disabled="actionBtn.disabled"
            @click="onActionBtn"
          />
        </view>
      </view>
    </scroll-view>
  </view>
</template>

<script>
import UButton from 'uview-plus/components/u-button/u-button.vue'
import ULazyLoad from 'uview-plus/components/u-lazy-load/u-lazy-load.vue'
import tabPage from '@/mixins/tabPage'
import { resolveResourceUrl } from '@/utils/resourceUrl'
import {
  getMyEnrollDetail,
  enrollPracticalTraining,
  cancelEnrollPracticalTraining
} from '@/api/practicalTraining'

const COVER = '/static/ai/hero.png'

/** 006001–006004 → 按钮状态索引（未开始/报名中/已报满/已截止） */
const TRAINING_STATUS_INDEX = {
  '006001': 0,
  '006002': 1,
  '006003': 2,
  '006004': 3
}

function formatDateTime(val) {
  if (val == null || val === '') return ''
  const s = String(val)
  return s.length >= 19 ? s.slice(0, 19) : s.slice(0, 10)
}

export default {
  components: {
    'up-button': UButton,
    'up-lazy-load': ULazyLoad
  },
  mixins: [tabPage],
  data() {
    return {
      navTitleKey: 'trainingDetailPage.navTitle',
      courseId: '',
      displayTitleRaw: '',
      typeCode: '',
      introduction: '',
      expectedOutcome: '',
      trainingTime: '',
      regStart: '',
      regEnd: '',
      enrolled: 0,
      total: 0,
      coverSrc: COVER,
      /** 当前用户是否已报名 */
      hasSigned: false,
      /** 接口返回：是否允许取消报名 */
      canCancelEnroll: false,
      detailLoading: false,
      actionSubmitting: false
    }
  },
  computed: {
    displayTitle() {
      return this.displayTitleRaw || this.$t('trainingDetailPage.titleFallback')
    },
    /** 0 未开始 1 报名中 2 已报满 3 已截止 */
    statusIndex() {
      if (TRAINING_STATUS_INDEX[this.typeCode] != null) {
        return TRAINING_STATUS_INDEX[this.typeCode]
      }
      return 1
    },
    registerRange() {
      if (this.regStart && this.regEnd) {
        return `${this.regStart} - ${this.regEnd}`
      }
      if (this.regStart) {
        return this.regStart
      }
      if (this.regEnd) {
        return this.regEnd
      }
      return this.$t('trainingDetailPage.noRegisterTime')
    },
    enrolledDisplay() {
      const cap = this.total > 0 ? this.total : 0
      const e = this.enrolled
      if (cap > 0) {
        return `${e}/${cap}`
      }
      return String(e)
    },
    placeText() {
      return this.trainingTime || this.$t('trainingDetailPage.noPlace')
    },
    introText() {
      return this.introduction || this.$t('trainingDetailPage.noIntro')
    },
    outcomeText() {
      return this.expectedOutcome || this.$t('trainingDetailPage.noOutcome')
    },
    canJoin() {
      return (
        this.statusIndex === 1 &&
        (this.total <= 0 || this.enrolled < this.total) &&
        !this.hasSigned &&
        !this.detailLoading &&
        !this.actionSubmitting
      )
    },
    canCancel() {
      return this.hasSigned && this.canCancelEnroll && !this.actionSubmitting
    },
    actionBtn() {
      const txt = (key) => this.$t(`trainingDetailPage.${key}`)
      const gray = (kind, key) => ({
        kind,
        text: txt(key),
        disabled: true,
        plain: true,
        hairline: true,
        buttonType: 'info'
      })
      if (this.detailLoading || this.actionSubmitting) {
        return gray('loading', 'btnLoading')
      }
      if (this.hasSigned) {
        if (this.canCancelEnroll) {
          return {
            kind: 'cancel',
            text: txt('btnCancel'),
            disabled: false,
            plain: true,
            hairline: false,
            buttonType: 'default'
          }
        }
        return gray('closed', 'btnClosed')
      }
      if (this.statusIndex === 0) {
        return gray('not_start', 'btnNotStart')
      }
      if (this.statusIndex === 3) {
        return gray('closed', 'btnClosed')
      }
      const isFull =
        this.statusIndex === 2 ||
        (this.statusIndex === 1 && this.total > 0 && this.enrolled >= this.total)
      if (isFull) {
        return gray('full', 'btnFull')
      }
      if (this.statusIndex === 1 && this.canJoin) {
        return {
          kind: 'join',
          text: txt('btnJoin'),
          disabled: false,
          plain: false,
          hairline: false,
          buttonType: 'primary'
        }
      }
      return gray('full', 'btnFull')
    }
  },
  onLoad(query) {
    const q = query || {}
    this.courseId = this.decodeQuery(q, 'id')
    this.displayTitleRaw = this.decodeQuery(q, 'title')
    this.typeCode = this.decodeQuery(q, 'type')
    this.introduction = this.decodeQuery(q, 'introduction')
    this.expectedOutcome = this.decodeQuery(q, 'expectedOutcome')

    const en = parseInt(this.decodeQuery(q, 'enrolled'), 10)
    const tot = parseInt(this.decodeQuery(q, 'total'), 10)
    this.enrolled = Number.isFinite(en) && en >= 0 ? en : 0
    this.total = Number.isFinite(tot) && tot >= 0 ? tot : 0

    const cover = this.decodeQuery(q, 'cover')
    this.coverSrc = cover ? resolveResourceUrl(cover) : COVER

    this.applyQueryDates(q)
  },
  onShow() {
    const p = uni.setNavigationBarTitle({
      title: this.displayTitleRaw || this.$t(this.navTitleKey)
    })
    if (p && typeof p.catch === 'function') {
      p.catch(() => {})
    }
    this.loadEnrollDetail()
  },
  methods: {
    applyQueryDates(q) {
      this.regStart = formatDateTime(this.decodeQuery(q, 'regStart'))
      this.regEnd = formatDateTime(this.decodeQuery(q, 'regEnd'))
      this.trainingTime = formatDateTime(this.decodeQuery(q, 'trainingTime'))
    },
    loadEnrollDetail() {
      if (!this.courseId) return Promise.resolve()
      this.detailLoading = true
      return getMyEnrollDetail(this.courseId)
        .then((res) => {
          const d = res.data
          if (d) {
            this.applyDetailVo(d)
            this.hasSigned = true
            this.canCancelEnroll = d.canCancel === true
          }
        })
        .catch(() => {
          this.hasSigned = false
          this.canCancelEnroll = false
        })
        .finally(() => {
          this.detailLoading = false
        })
    },
    applyDetailVo(d) {
      if (d.trainingTopic) {
        this.displayTitleRaw = d.trainingTopic
      }
      if (d.trainingStatus) {
        this.typeCode = d.trainingStatus
      }
      this.introduction = d.trainingIntro || this.introduction || ''
      this.expectedOutcome = d.expectedOutcome || this.expectedOutcome || ''
      const timeText = formatDateTime(d.trainingTime)
      const locationText = d.trainingLocation || ''
      this.trainingTime = timeText || locationText || this.trainingTime
      this.regStart = formatDateTime(d.registrationStartTime) || this.regStart
      this.regEnd = formatDateTime(d.registrationEndTime) || this.regEnd
      if (d.actualEnrolledCount != null) {
        this.enrolled = Number(d.actualEnrolledCount)
      }
      if (d.plannedHeadCount != null) {
        this.total = Number(d.plannedHeadCount)
      }
      if (d.coverFileUrl) {
        this.coverSrc = resolveResourceUrl(d.coverFileUrl)
      }
      uni.setNavigationBarTitle({
        title: this.displayTitleRaw || this.$t(this.navTitleKey)
      })
    },
    decodeQuery(q, key) {
      const raw = q && q[key]
      if (raw == null || raw === '') {
        return ''
      }
      try {
        return decodeURIComponent(String(raw))
      } catch (e) {
        return String(raw)
      }
    },
    onPreviewCover() {
      if (!this.coverSrc) return
      uni.previewImage({ urls: [this.coverSrc], current: 0 })
    },
    onActionBtn() {
      if (this.actionBtn.disabled) return
      const k = this.actionBtn.kind
      if (k === 'join') this.onJoin()
      else if (k === 'cancel') this.onCancelJoin()
    },
    onJoin() {
      if (!this.canJoin || !this.courseId) return
      this.actionSubmitting = true
      enrollPracticalTraining(this.courseId)
        .then(() => {
          uni.showToast({ title: this.$t('trainingDetailPage.toastJoined'), icon: 'none' })
          return this.loadEnrollDetail()
        })
        .finally(() => {
          this.actionSubmitting = false
        })
    },
    onCancelJoin() {
      if (!this.canCancel || !this.courseId) return
      this.actionSubmitting = true
      cancelEnrollPracticalTraining(this.courseId)
        .then(() => {
          uni.showToast({ title: this.$t('trainingDetailPage.toastCanceled'), icon: 'none' })
          this.hasSigned = false
          this.canCancelEnroll = false
          if (this.enrolled > 0) {
            this.enrolled -= 1
          }
          if (this.typeCode === '006003' && this.total > 0 && this.enrolled < this.total) {
            this.typeCode = '006002'
          }
        })
        .finally(() => {
          this.actionSubmitting = false
        })
    }
  }
}
</script>

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

.td-page {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 100%;
  box-sizing: border-box;
  background: $morandi-bg-page;
}

.td-scroll {
  flex: 1;
  min-height: 0;
  min-width: 0;
}

.td-inner {
  display: flex;
  flex-direction: column;
  gap: 24rpx;
  min-width: 0;
  padding: 24rpx 24rpx 48rpx;
  box-sizing: border-box;
}

.td-top {
  width: 100%;
  min-width: 0;
  border-radius: 16rpx;
  overflow: hidden;
  border: 1rpx solid $morandi-border;
  background: $morandi-bg-card-inner;
}

.td-cover {
  width: 100%;
  display: block;
}

.td-panel {
  min-width: 0;
  padding: 28rpx 24rpx;
  box-sizing: border-box;
  border-radius: 16rpx;
  background: #ffffff;
  border: 1rpx solid $morandi-border-soft;
}

.td-panel--info {
  display: flex;
  flex-direction: column;
  gap: 16rpx;
}

.td-title {
  font-size: 34rpx;
  font-weight: 700;
  line-height: 1.45;
  color: #111827;
  word-break: break-word;
  overflow-wrap: anywhere;
}

.td-line {
  font-size: 26rpx;
  line-height: 1.5;
  color: $morandi-text-secondary;
  word-break: break-word;
  overflow-wrap: anywhere;
}

.td-line--block {
  line-height: 1.55;
}

.td-panel--actions {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.td-btn {
  width: 100%;
}

.td-page.lang-bo {
  .td-title {
    font-size: 30rpx;
    line-height: 1.75;
    letter-spacing: 2rpx;
    font-family: 'Noto Sans Tibetan', 'PingFang SC', 'Microsoft YaHei', sans-serif;
  }

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

