<template>
  <view class="app-container pb-20">
    <StatusBar v-if="showStatusBar" />
    <TopBar v-if="showTopBar" title="排班管理" :show-back="showBack" />

    <!-- tab 页面专用标题栏 -->
    <view v-if="!showTopBar" class="bg-white px-4 py-3 flex items-center justify-between border-b border-gray-100">
      <text class="text-base font-semibold text-gray-800">排班管理</text>
    </view>

    <!-- 月份切换 -->
    <view class="bg-white px-4 py-3 flex items-center justify-center border-b border-gray-100">
      <view class="flex items-center">
        <view class="p-2" @click="changeMonth(-1)">
          <text class="uni-icons uniui-back text-gray-600"></text>
        </view>
        <text class="text-base font-semibold text-gray-800 mx-2">{{ currentYear }}年{{ currentMonth }}月</text>
        <view class="p-2" @click="changeMonth(1)">
          <text class="uni-icons uniui-arrowright text-gray-600"></text>
        </view>
      </view>
    </view>

    <!-- 页面中部操作按钮 -->
    <view class="bg-white px-4 py-2 flex items-center justify-center gap-6 border-b border-gray-100">
      <view class="text-sm text-blue-500 flex items-center" @click="goToToday">
        <text class="uni-icons uniui-calendar-filled mr-1"></text>
        今天
      </view>
      <view class="text-blue-500 text-sm flex items-center" @click="addSchedule">
        <text class="uni-icons uniui-plusempty mr-1"></text>
        新增排班
      </view>
    </view>

    <!-- 日历 -->
    <view class="mx-4 mt-4 bg-white rounded-xl shadow-sm p-4">
      <!-- 星期标题 -->
      <view class="flex mb-2">
        <view v-for="day in weekDays" :key="day" class="flex-1 text-center">
          <text class="text-xs text-gray-400">{{ day }}</text>
        </view>
      </view>

      <!-- 日期 -->
      <view v-for="(week, weekIndex) in calendarWeeks" :key="weekIndex" class="flex mb-2">
        <view
          v-for="(date, dateIndex) in week"
          :key="dateIndex"
          class="flex-1 h-14 flex flex-col items-center justify-center relative mx-1 rounded-xl transition-transform duration-150"
          :class="{
            'opacity-30': date.isOtherMonth,
            'bg-blue-50 text-primary': date.isToday && !isSelected(date),
            'bg-primary text-white shadow-sm': isSelected(date),
          }"
          hover-class="scale-down"
          :hover-start-time="0"
          :hover-stay-time="150"
          @click="selectDate(date)"
        >
          <text
            class="text-sm font-medium"
            :class="{
              'text-primary': date.isToday && !isSelected(date),
              'text-white': isSelected(date),
              'text-gray-800': !date.isToday && !isSelected(date)
            }"
          >
            {{ date.day }}
          </text>
          <view
            v-if="date.hasSchedule"
            class="w-2 h-2 rounded-full mt-1"
            :class="isSelected(date) ? 'bg-white' : 'bg-primary'"
          ></view>
        </view>
      </view>
    </view>

    <!-- 排班列表 -->
    <view class="px-4 mt-4">
      <view class="flex justify-between items-center mb-3">
        <text class="text-base font-semibold text-gray-800">{{ selectedDate }} 排班</text>
      </view>

      <view v-if="loading" class="py-10 text-center">
        <text class="text-gray-400">加载中...</text>
      </view>

      <view v-else-if="daySchedules.length === 0">
        <EmptyState message="该日无排班" />
      </view>

      <view v-else>
        <view
          v-for="schedule in daySchedules"
          :key="schedule.scheduleId"
          class="bg-white rounded-xl shadow-sm mb-3"
          hover-class="scale-down"
          :hover-start-time="0"
          :hover-stay-time="150"
          @click="viewSchedule(schedule)"
        >
          <uni-list-item
            :title="schedule.teamName || '未命名班组'"
            :note="(schedule.staffIds || '未分配人员') + ' | ' + (schedule.vehicleIds || '未分配车辆')"
            :right-text="getStatusText(schedule.status)"
            show-arrow
            clickable
          >
            <template #header>
              <view class="w-10 h-10 rounded-xl flex items-center justify-center mr-3" :class="getScheduleIconBgClass(schedule.shiftType)">
                <text class="uni-icons text-lg" :class="getScheduleIconClass(schedule.shiftType)"></text>
              </view>
            </template>
          </uni-list-item>
        </view>
      </view>
    </view>
    <!-- 新增排班底部弹窗 -->
    <view v-if="showModal" class="fixed inset-0 z-50 flex flex-col justify-end" style="padding-bottom: var(--window-bottom, 0);">
      <view class="absolute inset-0" style="background-color: rgba(0, 0, 0, 0.5);" @click="closeModal"></view>
      <view class="relative bg-white rounded-t-3xl w-full p-4 overflow-y-auto" style="max-height: 60vh; margin-bottom: 100rpx;">
        <view class="flex justify-between items-center mb-4">
          <text class="text-base font-semibold text-gray-800">{{ isDetail ? '排班详情' : '新增排班' }}</text>
          <text class="uni-icons uniui-close text-gray-400 p-2" @click="closeModal"></text>
        </view>

        <view class="mb-4">
          <text class="text-sm text-gray-600 block mb-1">选择班组</text>
          <picker mode="selector" :range="teamOptions" range-key="label" :value="teamIndex" @change="(e: any) => { const idx = e.detail.value; form.teamId = teamOptions[idx].value; onTeamChange(form.teamId) }">
            <view class="border border-gray-200 rounded-lg px-3 py-2 text-sm text-gray-800">
              {{ teamNameDisplay || '请选择班组' }}
            </view>
          </picker>
        </view>

        <view class="mb-4">
          <text class="text-sm text-gray-600 block mb-1">工作日期</text>
          <picker mode="date" :value="form.workDate" @change="(e: any) => form.workDate = e.detail.value">
            <view class="border border-gray-200 rounded-lg px-3 py-2 text-sm text-gray-800">
              {{ form.workDate || '请选择日期' }}
            </view>
          </picker>
        </view>

        <view class="mb-4">
          <text class="text-sm text-gray-600 block mb-1">排班类型</text>
          <view class="flex rounded-lg border border-gray-200 overflow-hidden">
            <view
              class="flex-1 py-2 text-center text-sm"
              :class="form.shiftType === 'month_plan' ? 'bg-primary text-white' : 'bg-white text-gray-600'"
              @click="form.shiftType = 'month_plan'"
            >月计划</view>
            <view
              class="flex-1 py-2 text-center text-sm"
              :class="form.shiftType === 'emergency' ? 'bg-red-500 text-white' : 'bg-white text-gray-600'"
              @click="form.shiftType = 'emergency'"
            >应急</view>
          </view>
        </view>

        <view class="mb-4">
          <text class="text-sm text-gray-600 block mb-1">选择车辆</text>
          <view class="flex flex-wrap gap-2">
            <view
              v-for="v in vehicleOptions"
              :key="v.value"
              class="px-2 py-1 rounded-lg text-xs border"
              :class="form.vehicleIds.includes(v.value) ? 'bg-primary text-white border-primary' : 'bg-white text-gray-600 border-gray-200'"
              @click="toggleVehicle(v.value)"
            >
              {{ v.label }}
            </view>
          </view>
        </view>

        <view class="mb-4">
          <text class="text-sm text-gray-600 block mb-1">备注（可选）</text>
          <textarea
            v-model="form.remark"
            class="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm"
            style="min-height: 80px;"
            placeholder="请输入备注信息..."
          />
        </view>

        <view class="flex gap-3 mt-4">
          <button class="flex-1 py-3 bg-white text-gray-600 rounded-xl border border-gray-200 text-sm transition-colors" hover-class="bg-gray-50" :hover-start-time="0" :hover-stay-time="150" @click="closeModal">取消</button>
          <button class="flex-1 py-3 bg-primary text-white rounded-xl text-sm transition-colors" hover-class="bg-blue-600" :hover-start-time="0" :hover-stay-time="150" @click="submitSchedule">{{ isDetail ? '保存' : '确认' }}</button>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import StatusBar from '../common/StatusBar.vue'
import TopBar from '../common/TopBar.vue'
import EmptyState from '../common/EmptyState.vue'
import UniList from '../uni-list/uni-list.vue'
import UniListItem from '../uni-list/uni-list-item.vue'
import { getSchedulesByDate, createSchedule, updateSchedule, getScheduleList } from '@/api/schedule'
import { getTeamSimpleList, getTeamMembers } from '@/api/team'
import { getVehicleSimpleList } from '@/api/vehicle'

withDefaults(
  defineProps<{
    showTopBar?: boolean
    showBack?: boolean
    showStatusBar?: boolean
  }>(),
  {
    showTopBar: true,
    showBack: true,
    showStatusBar: false,
  }
)

const loading = ref(false)
const schedules = ref<any[]>([])
const currentYear = ref(new Date().getFullYear())
const currentMonth = ref(new Date().getMonth() + 1)
const selectedDate = ref('')

const showModal = ref(false)
const isDetail = ref(false)
const currentScheduleId = ref<number | undefined>(undefined)
const teamOptions = ref<Array<{ value: number; label: string }>>([])
const vehicleOptions = ref<Array<{ value: number; label: string }>>([])

const form = ref({
  teamId: undefined as number | undefined,
  teamName: '',
  workDate: '',
  shiftType: 'month_plan' as 'month_plan' | 'emergency',
  vehicleIds: [] as number[],
  staffIds: '',
  status: 'idle',
  remark: '',
})

const teamIndex = computed(() => teamOptions.value.findIndex(t => t.value === form.value.teamId))
const teamNameDisplay = computed(() => teamOptions.value.find(t => t.value === form.value.teamId)?.label)

const weekDays = ['日', '一', '二', '三', '四', '五', '六']

const calendarWeeks = computed(() => {
  const year = currentYear.value
  const month = currentMonth.value
  const firstDay = new Date(year, month - 1, 1)
  const lastDay = new Date(year, month, 0)
  const firstWeekDay = firstDay.getDay()
  const daysInMonth = lastDay.getDate()

  const weeks: any[] = []
  let currentWeek: any[] = []

  const prevMonthDays = new Date(year, month - 1, 0).getDate()
  for (let i = firstWeekDay - 1; i >= 0; i--) {
    currentWeek.push({
      day: prevMonthDays - i,
      isOtherMonth: true,
      isToday: false,
      hasSchedule: false,
    })
  }

  for (let day = 1; day <= daysInMonth; day++) {
    const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`
    const isToday = dateStr === new Date().toISOString().split('T')[0]
    const hasSchedule = schedules.value.some(s => s.workDate === dateStr)

    currentWeek.push({
      day,
      isOtherMonth: false,
      isToday,
      hasSchedule,
      dateStr,
    })

    if (currentWeek.length === 7) {
      weeks.push(currentWeek)
      currentWeek = []
    }
  }

  if (currentWeek.length > 0) {
    for (let i = 1; currentWeek.length < 7; i++) {
      currentWeek.push({
        day: i,
        isOtherMonth: true,
        isToday: false,
        hasSchedule: false,
      })
    }
    weeks.push(currentWeek)
  }

  return weeks
})

const daySchedules = computed(() => {
  if (!selectedDate.value) return []
  return schedules.value.filter(s => s.workDate === selectedDate.value)
})

function changeMonth(delta: number) {
  let newMonth = currentMonth.value + delta
  if (newMonth > 12) {
    newMonth = 1
    currentYear.value++
  } else if (newMonth < 1) {
    newMonth = 12
    currentYear.value--
  }
  currentMonth.value = newMonth
}

function goToToday() {
  const now = new Date()
  currentYear.value = now.getFullYear()
  currentMonth.value = now.getMonth() + 1
  selectedDate.value = now.toISOString().split('T')[0]
}

function selectDate(date: any) {
  if (!date.isOtherMonth) {
    selectedDate.value = date.dateStr
  }
}

function isSelected(date: any): boolean {
  return date.dateStr === selectedDate.value
}

function getStatusText(status: string) {
  const map: Record<string, string> = {
    scheduled: '已排班',
    completed: '已完成',
    cancelled: '已取消',
  }
  return map[status] || status
}

function getScheduleIconBgClass(shiftType: string) {
  return shiftType === 'emergency' ? 'bg-red-50' : 'bg-blue-50'
}

function getScheduleIconClass(shiftType: string) {
  return shiftType === 'emergency' ? 'uniui-calendar-filled text-red-500' : 'uniui-calendar-filled text-blue-500'
}

function toggleVehicle(vehicleId: number) {
  const idx = form.value.vehicleIds.indexOf(vehicleId)
  if (idx >= 0) {
    form.value.vehicleIds.splice(idx, 1)
  } else {
    form.value.vehicleIds.push(vehicleId)
  }
}

async function addSchedule() {
  isDetail.value = false
  currentScheduleId.value = undefined
  resetForm()
  form.value.workDate = selectedDate.value
  showModal.value = true
  if (teamOptions.value.length === 0) {
    try {
      teamOptions.value = await getTeamSimpleList()
    } catch (e) {
      console.error('加载班组失败', e)
    }
  }
  if (vehicleOptions.value.length === 0) {
    try {
      vehicleOptions.value = await getVehicleSimpleList()
    } catch (e) {
      console.error('加载车辆失败', e)
    }
  }
}

function normalizeShiftType(shiftType: string | undefined): 'month_plan' | 'emergency' {
  if (!shiftType) return 'month_plan'
  if (shiftType === 'emergency' || shiftType.includes('应急')) return 'emergency'
  return 'month_plan'
}

function viewSchedule(schedule: any) {
  isDetail.value = true
  currentScheduleId.value = schedule.scheduleId
  form.value = {
    teamId: schedule.teamId,
    teamName: schedule.teamName || '',
    workDate: schedule.workDate || '',
    shiftType: normalizeShiftType(schedule.shiftType),
    vehicleIds: parseVehicleIds(schedule.vehicleIds),
    staffIds: schedule.staffIds || '',
    status: schedule.status || 'idle',
    remark: schedule.remark || '',
  }
  showModal.value = true
  if (teamOptions.value.length === 0) {
    getTeamSimpleList().then(res => { teamOptions.value = res }).catch(e => console.error('加载班组失败', e))
  }
  if (vehicleOptions.value.length === 0) {
    getVehicleSimpleList().then(res => { vehicleOptions.value = res }).catch(e => console.error('加载车辆失败', e))
  }
}

function parseVehicleIds(ids: string | number[] | undefined): number[] {
  if (!ids) return []
  if (Array.isArray(ids)) return ids.map(Number)
  return ids.split(',').map(s => Number(s.trim())).filter(n => !isNaN(n))
}

function closeModal() {
  showModal.value = false
  isDetail.value = false
  currentScheduleId.value = undefined
}

function resetForm() {
  form.value = {
    teamId: undefined,
    teamName: '',
    workDate: selectedDate.value,
    shiftType: 'month_plan',
    vehicleIds: [],
    staffIds: '',
    status: 'idle',
    remark: '',
  }
}

async function onTeamChange(teamId: number) {
  const team = teamOptions.value.find(t => t.value === teamId)
  form.value.teamName = team?.label || ''
  try {
    const members = await getTeamMembers(teamId)
    form.value.staffIds = members.map(m => m.staffId).join(',')
  } catch (e) {
    console.error('加载班组成员失败', e)
  }
}

async function submitSchedule() {
  if (!form.value.teamId) {
    uni.showToast({ title: '请选择班组', icon: 'none' })
    return
  }
  if (!form.value.workDate) {
    uni.showToast({ title: '请选择工作日期', icon: 'none' })
    return
  }
  try {
    const payload = {
      teamId: form.value.teamId,
      teamName: form.value.teamName,
      workDate: form.value.workDate,
      shiftType: form.value.shiftType,
      vehicleIds: form.value.vehicleIds.join(','),
      staffIds: form.value.staffIds,
      status: form.value.status,
      remark: form.value.remark,
    }
    if (isDetail.value && currentScheduleId.value) {
      await updateSchedule(currentScheduleId.value, payload)
      uni.showToast({ title: '保存成功', icon: 'success' })
    } else {
      await createSchedule(payload)
      uni.showToast({ title: '新增排班成功', icon: 'success' })
    }
    closeModal()
    resetForm()
    await fetchSchedules()
  } catch (e) {
    console.error(isDetail.value ? '保存排班失败' : '新增排班失败', e)
  }
}

async function fetchSchedules() {
  if (!selectedDate.value) return
  loading.value = true
  try {
    const [dayRes, monthRes] = await Promise.all([
      getSchedulesByDate(selectedDate.value),
      getScheduleList(currentYear.value, currentMonth.value)
    ])
    const dayList = dayRes || []
    const monthList = monthRes?.rows || monthRes || []
    const allSchedules = [...dayList]
    monthList.forEach((s: any) => {
      if (!allSchedules.some((x: any) => x.scheduleId === s.scheduleId)) {
        allSchedules.push(s)
      }
    })
    schedules.value = allSchedules
  } catch (error) {
    console.error('获取排班列表失败:', error)
  } finally {
    loading.value = false
  }
}

watch([selectedDate, currentMonth], fetchSchedules)

onMounted(() => {
  const today = new Date().toISOString().split('T')[0]
  selectedDate.value = today
  fetchSchedules()
})
</script>

<style scoped>
.scale-down {
  transition: transform 0.15s ease;
  transform: scale(0.95);
}
</style>
