<template>
  <a-modal v-model:visible="visible" :title="modalTitle" :width="980" :footer="false" unmount-on-close esc-to-close
    draggable class="account-detail-modal">
    <a-spin :loading="loading" style="width: 100%">
      <template v-if="account">
        <div class="account-header">
          <a-avatar :size="64">
            <img :alt="account.name ?? ''" :src="account.user_avatar || defaultAvatar" />
          </a-avatar>
          <div class="account-header-main">
            <div class="account-name">{{ account.name || '未同步姓名' }}</div>
            <div class="account-meta">
              <span>学号 {{ account.student_num }}</span>
              <a-divider direction="vertical" />
              <span>{{ sexLabel }}</span>
              <a-divider direction="vertical" />
              <span>{{ account.grade_id || '-' }} 级</span>
            </div>
          </div>
          <a-tag :color="stateTag.color">{{ stateTag.text }}</a-tag>
        </div>

        <a-descriptions :column="isMobile ? 1 : 3" bordered size="small" class="account-desc">
          <a-descriptions-item v-if="admin" label="创建用户">{{ account.create_user || '-' }}</a-descriptions-item>
          <a-descriptions-item v-if="admin" label="人脸状态">{{ faceStateLabel }}</a-descriptions-item>
          <a-descriptions-item v-if="admin" label="手机型号">{{ account.deviceModel || '-' }}</a-descriptions-item>
          <a-descriptions-item label="学院">{{ account.academy_name || '-' }}</a-descriptions-item>
          <a-descriptions-item label="跑区">{{ account.area || '随机分配' }}</a-descriptions-item>
          <a-descriptions-item label="通知方式">{{ noticeLabel }}</a-descriptions-item>
          <a-descriptions-item label="自动乐跑">
            <a-tag v-if="account.auto_run" color="green">{{ autoRunLabel }}</a-tag>
            <a-tag v-else color="red">关闭</a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="自动星期">{{ autoDayLabel }}</a-descriptions-item>
          <a-descriptions-item label="自动时段">{{ autoTimeLabel }}</a-descriptions-item>
          <a-descriptions-item label="学期目标">{{ termProgressLabel }}</a-descriptions-item>
          <a-descriptions-item label="添加时间">{{ formatTime(account.create_time) }}</a-descriptions-item>
          <a-descriptions-item label="上次更新">{{ account.update_time ? formatTime(account.update_time) : '待登录'
            }}</a-descriptions-item>
          <a-descriptions-item v-if="admin" label="UA" :span="3">{{ account.userAgent || '-' }}</a-descriptions-item>
          <a-descriptions-item label="备注" :span="3">{{ account.notes || '-' }}</a-descriptions-item>
        </a-descriptions>

        <div class="section-title">
          <span>乐跑日历</span>
          <a-select v-model="calendarYear" :options="yearOptions" size="small" style="width: 110px" />
        </div>
        <Chart :options="calendarOption" height="180px" width="100%" />

        <div class="section-title">
          <span>乐跑记录</span>
          <span class="record-count">{{ activeRecordCountLabel }}</span>
        </div>
        <a-tabs v-model:active-key="recordTab" @change="handleRecordTabChange">
          <a-tab-pane key="platform" title="平台记录">
            <a-table :data="records" :pagination="{ pageSize: 8, showTotal: true }" :scroll="{ x: 900, y: 280 }"
              size="small" row-key="id" :bordered="false">
              <template #columns>
                <a-table-column v-if="admin" title="所属用户" :width="120">
                  <template #cell="{ record }">{{ record.username || '-' }}</template>
                </a-table-column>
                <a-table-column title="状态" :width="200">
                  <template #cell="{ record }">
                    <div class="state">
                      <div class="circle" :class="record.result?.record_failed_reason === '自动确认有效' ? 'one' : 'else'" />
                      {{ record.result?.record_failed_reason }}
                    </div>
                  </template>
                </a-table-column>
                <a-table-column title="跑区" :width="180">
                  <template #cell="{ record }">{{ record.result?.pass_tit }}</template>
                </a-table-column>
                <a-table-column title="距离" :width="90">
                  <template #cell="{ record }">{{ record.result?.distance }} Km</template>
                </a-table-column>
                <a-table-column title="时长" :width="100">
                  <template #cell="{ record }">{{ formatSecondsToMinSec(record.result?.time) }}</template>
                </a-table-column>
                <a-table-column title="配速" :width="80">
                  <template #cell="{ record }">
                    {{ calculatePace(record.result?.time, record.result?.distance) }}
                  </template>
                </a-table-column>
                <a-table-column title="乐跑时间" :width="160">
                  <template #cell="{ record }">{{ formatTime(record.time) }}</template>
                </a-table-column>
                <a-table-column title="" :width="90" :fixed="tableFixed('right')">
                  <template #cell="{ record }">
                    <a-button type="text" size="small" @click="openPlatformRecordDetail(record)">详情</a-button>
                  </template>
                </a-table-column>
              </template>
            </a-table>
          </a-tab-pane>
          <a-tab-pane key="official" title="官方记录" :disabled="!canViewOfficialRecords">
            <a-alert v-if="!canViewOfficialRecords" type="warning" class="official-record-alert"
              content="仅状态为正常的账号可查看官方记录，请使用登录器更新账号后再试。" />
            <a-table :data="officialRecords" :loading="officialLoading" :pagination="officialPaginationConfig"
              :scroll="{ x: 900, y: 280 }" size="small" row-key="id" :bordered="false"
              @page-change="handleOfficialPageChange">
              <template #columns>
                <a-table-column title="状态" :width="70">
                  <template #cell="{ record }">
                    <a-tag :color="String(record.record_status) === '1' ? 'green' : 'orangered'">
                      {{ officialRecordStatus(record) }}
                    </a-tag>
                  </template>
                </a-table-column> 
                <a-table-column title="跑区" :width="160">
                  <template #cell="{ record }">{{ record.title || '-' }}</template>
                </a-table-column>
                <a-table-column title="类型" :width="100">
                  <template #cell="{ record }">{{ record.tag || record.point_type_str || '-' }}</template>
                </a-table-column>
                <a-table-column title="配速" :width="80">
                  <template #cell="{ record }">
                    {{ calculatePace(Number(record.end_time) - Number(record.start_time), record.distance) }}
                  </template>
                </a-table-column>
                <a-table-column title="距离" :width="90">
                  <template #cell="{ record }">{{ record.distance || '-' }} Km</template>
                </a-table-column>
                <a-table-column title="时长" :width="100">
                  <template #cell="{ record }">{{ formatOfficialDuration(record) }}</template>
                </a-table-column>
                <a-table-column title="乐跑时间" :width="160">
                  <template #cell="{ record }">{{ formatUnixTime(record.start_time) }}</template>
                </a-table-column>
              </template>
            </a-table>
          </a-tab-pane>
        </a-tabs>
      </template>
    </a-spin>
  </a-modal>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useRouter } from 'vue-router'
import {
  lepaoRecords,
  adminLepaoRecords,
  officialTermRecords,
  adminOfficialTermRecords
} from '@/api/lepao'
import { Notification, Message } from '@arco-design/web-vue'
import useChartOption from '@/hooks/chart-option'
import { useResponsiveTable } from '@/hooks/useResponsiveTable'

const props = defineProps({
  admin: {
    type: Boolean,
    default: false
  }
})

const defaultAvatar = 'https://lepao-cloud.xxoo365.top/view.php/25aa126dc406974ff3579a99a2c6501a.png'

const auto_day = [
  { label: '周一', value: 1 },
  { label: '周二', value: 2 },
  { label: '周三', value: 3 },
  { label: '周四', value: 4 },
  { label: '周五', value: 5 },
  { label: '周六', value: 6 },
  { label: '周日', value: 0 }
]

const auto_time_options = [
  { label: '随机分配', value: -1 },
  ...Array.from({ length: 17 }, (_, i) => {
    const hour = i + 7
    return { label: `${hour} ~ ${hour + 1}时`, value: hour }
  })
]

const visible = ref(false)
const loading = ref(false)
const account = ref(null)
const records = ref([])
const officialRecords = ref([])
const officialLoading = ref(false)
const officialSummary = ref({})
const officialPagination = ref({ current: 1, pageSize: 10, total: 0 })
const recordTab = ref('platform')
const calendarYear = ref(new Date().getFullYear())
const { isMobile, tableFixed } = useResponsiveTable()
const router = useRouter()

const modalTitle = computed(() => {
  if (!account.value) return '账号详情'
  const name = account.value.name || account.value.student_num
  return `${name} · 账号详情`
})

const sexLabel = computed(() => {
  if (!account.value) return '-'
  if (account.value.sex === 1) return '男'
  if (account.value.sex === 2) return '女'
  return '-'
})

const stateTag = computed(() => {
  const state = account.value?.state
  if (state === 0) return { text: '需登录', color: 'orangered' }
  if (state === 1) return { text: '正常', color: 'green' }
  return { text: '状态异常', color: 'red' }
})

const noticeLabel = computed(() => {
  const item = account.value
  if (!item) return '-'
  if (item.notice_type === 'email') return `📧 ${item.email || '未绑定'}`
  if (item.notice_type === 'bot') return `🤖 ${item.bot_account || '未绑定'}`
  return '无通知'
})

const autoRunLabel = computed(() => {
  const item = account.value
  if (!item?.auto_run) return '关闭'
  return item.target_count === 0 ? '开启 · 不限次' : `开启 · ${item.target_count} 次`
})

const autoDayLabel = computed(() => {
  const item = account.value
  if (!item?.auto_run || !item.auto_day?.length) return '-'
  return item.auto_day
    .slice()
    .sort((a, b) => {
      if (a === 0) return 1
      if (b === 0) return -1
      return a - b
    })
    .map((day) => auto_day.find((d) => d.value === day)?.label)
    .join('、')
})

const autoTimeLabel = computed(() => {
  const item = account.value
  if (!item?.auto_run) return '-'
  if (item.auto_time === -1) {
    if (item.today_auto_time) return `随机 · 今日 ${item.today_auto_time} 时`
    return '随机 · 待分配'
  }
  return auto_time_options.find((t) => t.value === item.auto_time)?.label || '-'
})

const termProgressLabel = computed(() => {
  const item = account.value
  if (!item) return '-'
  if (item.term_num != null && item.total_num != null && item.term_num !== item.total_num) {
    return `${item.total_num} / ${item.term_num}`
  }
  return '已完成'
})

const faceStateLabel = computed(() => {
  const faceState = account.value?.face_state
  if (faceState === 0) return '未采集'
  if (faceState === 1) return '已通过'
  if (faceState != null) return '不通过'
  return '-'
})

const canViewOfficialRecords = computed(() => account.value?.state === 1)

const activeRecordCountLabel = computed(() => {
  if (recordTab.value === 'official') {
    const total = officialPagination.value.total || officialRecords.value.length
    return `官方记录共 ${total} 条，有效次数 ${officialSummary.value?.total_score_num ?? 0} 次（${officialSummary.value?.term_name ?? '本学期'}）`
  }
  return `平台记录共 ${records.value.length} 条`
})

const officialPaginationConfig = computed(() => ({
  current: officialPagination.value.current,
  pageSize: officialPagination.value.pageSize,
  total: officialPagination.value.total || officialRecords.value.length,
  showTotal: true,
  showPageSize: false
}))

const yearOptions = computed(() => {
  const years = new Set([calendarYear.value, new Date().getFullYear()])
  records.value.forEach((record) => {
    years.add(new Date(record.time).getFullYear())
  })
  return Array.from(years)
    .sort((a, b) => b - a)
    .map((year) => ({ label: `${year} 年`, value: year }))
})

const formatDateKey = (timestamp) => {
  const d = new Date(timestamp)
  const y = d.getFullYear()
  const m = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  return `${y}-${m}-${day}`
}

const buildCalendarSeriesData = () => {
  const counter = new Map()
  records.value.forEach((record) => {
    const date = new Date(record.time)
    if (date.getFullYear() !== calendarYear.value) return
    const key = formatDateKey(record.time)
    counter.set(key, (counter.get(key) || 0) + 1)
  })
  return Array.from(counter.entries()).map(([date, count]) => [date, count])
}

const { chartOption: calendarOption } = useChartOption(() => {
  const seriesData = buildCalendarSeriesData()
  const maxCount = Math.max(...seriesData.map((item) => item[1]), 1)

  return {
    tooltip: {
      position: 'top',
      formatter(params) {
        if (!params?.data) return ''
        return `${params.data[0]}<br/>乐跑 ${params.data[1]} 次`
      }
    },
    visualMap: {
      min: 0,
      max: maxCount,
      show: false,
      inRange: {
        color: ['#fff0f5', '#FE82A5']
      }
    },
    calendar: {
      top: 36,
      left: 40,
      right: 20,
      cellSize: ['auto', 18],
      range: String(calendarYear.value),
      itemStyle: {
        borderWidth: 0.5,
        borderColor: 'var(--color-border-2)'
      },
      yearLabel: { show: true, fontSize: 12 },
      monthLabel: { fontSize: 11 },
      dayLabel: { fontSize: 10 }
    },
    series: [
      {
        type: 'heatmap',
        coordinateSystem: 'calendar',
        data: seriesData
      }
    ]
  }
})

const formatTime = (time) => {
  if (!time) return '-'
  return new Date(time).toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  })
}

const formatUnixTime = (time) => {
  const timestamp = Number(time)
  if (!Number.isFinite(timestamp) || timestamp <= 0) return '-'
  return formatTime(timestamp * 1000)
}

function calculatePace(seconds, kilometers) {
  if (!seconds || !kilometers) return '-'
  const paceInSeconds = seconds / kilometers
  const minutes = Math.floor(paceInSeconds / 60)
  const remainingSeconds = Math.round(paceInSeconds % 60)
  return `${minutes}'${remainingSeconds.toString().padStart(2, '0')}''`
}

function formatSecondsToMinSec(totalSeconds) {
  if (!totalSeconds && totalSeconds !== 0) return '-'
  const minutes = Math.floor(totalSeconds / 60)
  const seconds = totalSeconds % 60
  return `${minutes}分${seconds.toString().padStart(2, '0')}秒`
}

const formatOfficialDuration = (record) => {
  const start = Number(record?.start_time)
  const end = Number(record?.end_time)
  if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return '-'
  return formatSecondsToMinSec(end - start)
}

const officialRecordStatus = (record) => {
  const status = String(record?.record_status ?? '')
  if (status === '1') return '有效'
  return '无效'
}

const fetchAllRecords = async (studentNum) => {
  const all = []
  let current = 1
  const pagesize = 100
  let total = 0

  const fetchRecords = props.admin ? adminLepaoRecords : lepaoRecords

  do {
    const res = await fetchRecords({
      lepao_account: studentNum,
      pagesize,
      current
    })
    if (!res || res.code !== 0) {
      throw new Error(res?.msg || '获取乐跑记录失败')
    }
    all.push(...(res.data || []))
    total = res.pagination?.total ?? all.length
    current += 1
  } while (all.length < total)

  return all.sort((a, b) => b.time - a.time)
}

const fetchOfficialRecords = async (page = 1) => {
  if (!account.value?.student_num) return
  if (!canViewOfficialRecords.value) {
    Message.warning('请使用登录器更新账号后查看官方乐跑记录')
    return
  }

  officialLoading.value = true
  try {
    const fetchRecords = props.admin ? adminOfficialTermRecords : officialTermRecords
    const res = await fetchRecords({
      student_num: account.value.student_num,
      page
    })
    if (!res || res.code !== 0) {
      if (account.value && String(res?.msg || '').includes('登录')) {
        account.value.state = 0
      }
      throw new Error(res?.msg || '获取乐跑记录失败')
    }

    const data = res.data || {}
    officialSummary.value = data
    officialRecords.value = data.list || []
    officialPagination.value = {
      ...officialPagination.value,
      current: data.page || page,
      total: Number(data.total_num || officialRecords.value.length)
    }
  } catch (error) {
    Notification.error({
      title: '获取官方乐跑记录失败',
      content: error.message || '请稍后再试'
    })
  } finally {
    officialLoading.value = false
  }
}

const handleRecordTabChange = (key) => {
  if (key !== 'official') return
  if (!canViewOfficialRecords.value) {
    recordTab.value = 'platform'
    Message.warning('请使用登录器更新账号后查看官方记录')
    return
  }
  if (officialRecords.value.length === 0) {
    fetchOfficialRecords(1)
  }
}

const handleOfficialPageChange = (page) => {
  fetchOfficialRecords(page)
}

const openPlatformRecordDetail = (record) => {
  const key = record.public_id || record.id
  if (!key) {
    Message.warning('该记录缺少可用标识，无法打开详情')
    return
  }
  visible.value = false
  const path = props.admin
    ? `/admin/lepaoRecords/${encodeURIComponent(String(key))}`
    : `/lepao/recordDetail/${encodeURIComponent(String(key))}`
  router.push(path)
}

const openModal = async (record) => {
  if (!record?.student_num) return
  account.value = record
  visible.value = true
  loading.value = true
  records.value = []
  officialRecords.value = []
  officialSummary.value = {}
  officialPagination.value = { current: 1, pageSize: 10, total: 0 }
  recordTab.value = 'platform'

  try {
    const list = await fetchAllRecords(record.student_num)
    records.value = list
    if (list.length > 0) {
      calendarYear.value = new Date(list[0].time).getFullYear()
    } else {
      calendarYear.value = new Date().getFullYear()
    }
  } catch (error) {
    Notification.error({
      title: '获取乐跑记录失败',
      content: error.message || '请稍后再试'
    })
  } finally {
    loading.value = false
  }
}

defineExpose({ openModal })
</script>

<style scoped lang="less">
.account-detail-modal {
  :deep(.arco-modal-body) {
    max-height: 78vh;
    overflow-y: auto;
  }
}

.account-header {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
}

.account-header-main {
  flex: 1;
  min-width: 0;
}

.account-name {
  font-size: 18px;
  font-weight: 600;
  line-height: 1.4;
}

.account-meta {
  margin-top: 4px;
  color: var(--color-text-3);
  font-size: 13px;
}

.account-desc {
  margin-bottom: 20px;
}

.section-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 16px 0 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-1);
}

.record-count {
  font-size: 12px;
  font-weight: 400;
  color: var(--color-text-3);
}

.official-record-alert {
  margin-bottom: 12px;
}

.state {
  display: flex;
  align-items: center;

  .circle {
    border-radius: 50%;
    height: 8px;
    width: 8px;
    margin-right: 6px;
    flex-shrink: 0;
  }

  .one {
    background-color: rgb(var(--green-6));
  }

  .else {
    background-color: rgb(var(--red-6));
  }
}

@media (max-width: 768px) {
  .account-header {
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 10px;
  }

  .section-title {
    flex-wrap: wrap;
    gap: 8px;
  }

  .record-count {
    width: 100%;
  }

  .account-detail-modal {
    :deep(.arco-modal) {
      width: calc(100vw - 16px) !important;
      max-width: calc(100vw - 16px) !important;
      margin: 8px auto !important;
    }

    :deep(.arco-descriptions-bordered .arco-descriptions-item) {
      width: 100%;
    }

    :deep(.arco-descriptions-bordered .arco-descriptions-item-label),
    :deep(.arco-descriptions-bordered .arco-descriptions-item-value) {
      padding: 8px 10px;
      font-size: 12px;
      line-height: 1.45;
    }
  }
}
</style>
