<template>
  <view class="page">
    <view class="card">
      <view class="card-title">信息填写</view>

      <!-- 时间：首行 时间* + 右侧橙色链接；次行并排两个时间选择框 -->
      <view class="section section--time">
        <view class="time-label-row">
          <text class="label label--req">时间</text>
          <text class="link" @tap.stop="openTableInfoPopup">(查看桌台信息)</text>
        </view>
        <view class="time-row">
          <view class="time-col">
            <view class="time-box time-box--readonly">
              <text class="time-clock">🕐</text>
              <text class="time-text">{{ form.startTime || '—' }}</text>
            </view>
          </view>
          <view class="time-col">
            <picker class="time-picker" mode="time" :value="form.endTime" @change="onEndTimeChange">
              <view class="time-box">
                <text class="time-clock">🕐</text>
                <text :class="['time-text', { 'is-placeholder': !form.endTime }]">
                  {{ form.endTime || '选择结束时间(次日)' }}
                </text>
              </view>
            </picker>
          </view>
        </view>
      </view>

      <view class="divider" />

      <view class="row">
        <text class="label">姓名</text>
        <input
          v-model="form.name"
          class="input"
          type="text"
          placeholder="请输入姓名"
          placeholder-class="input-ph"
        />
      </view>

      <view class="divider" />

      <view class="row row-gender">
        <text class="label">性别</text>
        <view class="gender-group">
          <view
            class="gender-opt"
            :class="{ active: form.gender === 'mr' }"
            @tap.stop="selectGender('mr')"
          >
            <view class="gender-dot" :class="{ on: form.gender === 'mr' }">
              <view v-if="form.gender === 'mr'" class="gender-dot-inner" />
            </view>
            <text class="gender-txt">先生</text>
          </view>
          <view
            class="gender-opt"
            :class="{ active: form.gender === 'ms' }"
            @tap.stop="selectGender('ms')"
          >
            <view class="gender-dot" :class="{ on: form.gender === 'ms' }">
              <view v-if="form.gender === 'ms'" class="gender-dot-inner" />
            </view>
            <text class="gender-txt">女士</text>
          </view>
        </view>
      </view>

      <view class="divider" />

      <view class="row">
        <text class="label">电话</text>
        <input
          v-model="form.phone"
          class="input"
          type="number"
          maxlength="11"
          placeholder="请输入手机号"
          placeholder-class="input-ph"
        />
      </view>

      <view class="divider" />

      <view class="row row-remark">
        <text class="label label-top">备注</text>
        <view class="remark-wrap">
          <textarea
            v-model="form.remark"
            class="textarea"
            placeholder="请输入"
            placeholder-class="input-ph"
            maxlength="30"
            :show-confirm-bar="false"
          />
          <text class="remark-count">{{ (form.remark || '').length }}/30</text>
        </view>
      </view>
    </view>

    <view class="footer-spacer" />
    <view class="footer-bar">
      <view class="footer-btn hover-active" @click="handleConfirm">确定</view>
    </view>

    <!-- 桌台信息：底部弹窗（可预约时段） -->
    <view v-if="tableInfoPopupOpen" class="table-popup-root">
      <view class="table-popup-mask" @click="closeTableInfoPopup" />
      <view class="table-popup-sheet" @click.stop>
        <view class="table-popup-head">
          <text class="table-popup-title">桌台信息 ({{ tableDisplayCode }})</text>
          <view class="table-popup-close" hover-class="table-popup-close--active" @click="closeTableInfoPopup">
            <text class="table-popup-close-x">×</text>
          </view>
        </view>
        <view class="table-slot-grid">
          <view v-if="tableInfoLoading" class="table-popup-hint">加载中…</view>
          <view v-else-if="!tableTimeSlots.length" class="table-popup-hint table-popup-hint--muted">暂无可预约时段</view>
          <template v-else>
            <view v-for="(slot, i) in tableTimeSlots" :key="i" class="table-slot-tag">
              <text class="table-slot-tag-text">{{ slot.label }}</text>
            </view>
          </template>
        </view>
        <view class="table-popup-safe" />
      </view>
    </view>
  </view>
</template>

<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { reactive, ref } from 'vue';
import { useUserStore } from '@/store/user.js';
import {
  GetReservationDetailByStoreTableRecord,
  GetTableDiningStatus,
  PostDiningWalkInReservation
} from '@/api/dining.js';

const userStore = useUserStore();

/** 桌台信息弹窗 */
const tableInfoPopupOpen = ref(false);
const tableInfoLoading = ref(false);
const tableDisplayCode = ref('—');
/** 桌台可预约时段（接口返回），仅展示 */
const tableTimeSlots = ref([]);

const form = reactive({
  startTime: '',
  endTime: '',
  name: '',
  gender: '', // mr 先生 / ms 女士
  phone: '',
  remark: ''
});

/** 统一性别为 mr/ms，兼容接口/缓存/用户信息中的多种写法 */
function normalizeGender(val) {
  if (val == null || val === '') return '';
  const raw = String(val).trim();
  const s = raw.toLowerCase();
  if (raw === '男' || raw === '先生') return 'mr';
  if (raw === '女' || raw === '女士') return 'ms';
  if (['mr', 'male', 'm', '1'].includes(s)) return 'mr';
  if (['ms', 'female', 'f', '2'].includes(s)) return 'ms';
  return '';
}

function selectGender(v) {
  form.gender = v === 'ms' ? 'ms' : 'mr';
}

function syncPhoneFromUser() {
  const u = userStore.getUserInfo || {};
  const p = u.phone ?? u.mobile ?? u.contactPhone ?? '';
  if (p && !form.phone) form.phone = String(p);
  const n = u.nickName ?? u.nickname ?? u.name ?? '';
  if (n && !form.name) form.name = String(n);
}

/** 开始时间固定为进入页时的当前时间（HH:mm），不可改 */
function initStartTimeToNow() {
  const d = new Date();
  const h = String(d.getHours()).padStart(2, '0');
  const m = String(d.getMinutes()).padStart(2, '0');
  form.startTime = `${h}:${m}`;
}

onLoad(() => {
  initStartTimeToNow();
  syncPhoneFromUser();
  try {
    const raw = uni.getStorageSync('diningForm');
    if (raw && typeof raw === 'string') {
      const o = JSON.parse(raw);
      if (o && typeof o === 'object') {
        // 不恢复 startTime，始终以当前时间为准
        if (o.endTime) form.endTime = o.endTime;
        if (o.name) form.name = o.name;
        const gCached = normalizeGender(o.gender);
        if (gCached) form.gender = gCached;
        if (o.phone) form.phone = o.phone;
        if (o.remark) form.remark = o.remark;
      }
    }
  } catch {
    /* ignore */
  }
  // 缓存未带性别时，从登录用户信息同步（男/女、mile/female 等）
  if (!form.gender) {
    const u = userStore.getUserInfo || {};
    const gUser = normalizeGender(u.gender);
    if (gUser) form.gender = gUser;
  }
  // 缓存恢复的结束时间若早于开始时间（同日），清空需重选
  if (form.endTime && form.startTime && !isEndAfterStartSameDay(form.endTime, form.startTime)) {
    form.endTime = '';
  }
});

/** HH:mm 转当天分钟数 */
function timeStrToMinutes(t) {
  if (t == null || t === '') return NaN;
  const parts = String(t).trim().split(':');
  const h = parseInt(parts[0], 10);
  const m = parseInt(parts[1] ?? '0', 10);
  if (Number.isNaN(h) || Number.isNaN(m)) return NaN;
  return h * 60 + m;
}

/** 同日：结束时间须严格大于开始时间 */
function isEndAfterStartSameDay(endStr, startStr) {
  const end = timeStrToMinutes(endStr);
  const start = timeStrToMinutes(startStr);
  if (Number.isNaN(end) || Number.isNaN(start)) return false;
  return end > start;
}

const END_AFTER_START_TIP = '结束时间大于开始时间（同日）';

function onEndTimeChange(e) {
  const end = e.detail.value || '';
  if (!end) {
    form.endTime = '';
    return;
  }
  if (form.startTime && !isEndAfterStartSameDay(end, form.startTime)) {
    uni.showToast({ title: END_AFTER_START_TIP, icon: 'none' });
    return;
  }
  form.endTime = end;
}

function resolveTableDisplayCode() {
  const no =
    uni.getStorageSync('currentTableNumber') ||
    uni.getStorageSync('currentTableNo') ||
    uni.getStorageSync('tableNumber') ||
    '';
  const tid = uni.getStorageSync('currentTableId') || '';
  if (no) return String(no);
  if (tid) return String(tid);
  return '—';
}

/** 桌台信息弹窗标题：优先用 /store/dining/table-dining-status 返回的 tableNumber */
function pickTableNumberFromDiningStatus(data) {
  if (data == null || typeof data !== 'object') return '';
  const d = data.data != null && typeof data.data === 'object' ? data.data : data;
  const n = d.tableNumber ?? d.tableNo ?? d.tableName ?? d.tableCode;
  return n != null && n !== '' ? String(n) : '';
}

/** 从预约详情里取桌号展示文案 */
function pickTableDisplayFromDetail(data, fallbackTableId) {
  const r = data?.record && typeof data.record === 'object' ? data.record : data;
  if (!r || typeof r !== 'object') {
    const fb = resolveTableDisplayCode();
    return fb !== '—' ? fb : String(fallbackTableId || '—');
  }
  const code =
    r.tableNumber ??
    r.tableNo ??
    r.tableName ??
    r.tableCode ??
    data?.tableNumber ??
    data?.tableNo ??
    r.tableId ??
    data?.tableId;
  if (code != null && code !== '') return String(code);
  const fb = resolveTableDisplayCode();
  return fb !== '—' ? fb : String(fallbackTableId || '—');
}

function mapListToSlotLabels(list) {
  if (!Array.isArray(list)) return [];
  return list
    .map((item) => {
      if (item == null) return null;
      if (typeof item === 'string') return { label: item };
      const start = item.startTime ?? item.start ?? item.begin ?? '';
      const end = item.endTime ?? item.end ?? item.finish ?? '';
      if (start !== '' && end !== '') {
        const s = String(start).length > 5 ? String(start).slice(11, 16) : String(start).slice(0, 5);
        const e = String(end).length > 5 ? String(end).slice(11, 16) : String(end).slice(0, 5);
        return { label: `${s}–${e}` };
      }
      const label = item.label ?? item.timeRange ?? item.slotText ?? item.name ?? item.text ?? '';
      return label ? { label: String(label) } : null;
    })
    .filter(Boolean);
}

/** 从预约详情里解析可预约时段列表 */
function mapReservationSlots(data) {
  if (Array.isArray(data)) return mapListToSlotLabels(data);
  if (!data || typeof data !== 'object') return [];
  const nested = data.record && typeof data.record === 'object' ? data.record : {};
  const list =
    data.timeSlots ??
    data.timeSlotList ??
    data.slots ??
    data.reservableTimeSlots ??
    data.periods ??
    data.availableSlots ??
    data.reservationSlots ??
    nested.timeSlots ??
    nested.slots ??
    (Array.isArray(data.list) ? data.list : null) ??
    (Array.isArray(data.records) ? data.records : null);
  return mapListToSlotLabels(list);
}

async function openTableInfoPopup() {
  const storeId = uni.getStorageSync('currentStoreId') || '';
  const tableId = uni.getStorageSync('currentTableId') || '';
  if (!storeId || !tableId) {
    uni.showToast({ title: '缺少门店或桌台信息', icon: 'none' });
    return;
  }
  tableDisplayCode.value = resolveTableDisplayCode();
  tableTimeSlots.value = [];
  tableInfoLoading.value = true;
  tableInfoPopupOpen.value = true;
  let titleFromDiningStatus = '';
  try {
    const statusData = await GetTableDiningStatus(tableId, { loading: false });
    titleFromDiningStatus = pickTableNumberFromDiningStatus(statusData);
    if (titleFromDiningStatus) tableDisplayCode.value = titleFromDiningStatus;
  } catch {
    /* 标题保持本地缓存/桌号兜底 */
  }
  try {
    const data = await GetReservationDetailByStoreTableRecord({
      storeId,
      userReservationTableId: tableId
    });
    if (!titleFromDiningStatus) {
      tableDisplayCode.value = pickTableDisplayFromDetail(data, tableId);
    }
    tableTimeSlots.value = mapReservationSlots(data);
  } catch {
    tableTimeSlots.value = [];
    if (!titleFromDiningStatus) {
      tableDisplayCode.value = resolveTableDisplayCode();
    }
  } finally {
    tableInfoLoading.value = false;
  }
}

function closeTableInfoPopup() {
  tableInfoPopupOpen.value = false;
}

/** 表单性别 mr/ms → 接口 reservationUserGender：0 男 1 女 */
function genderToReservationCode(g) {
  if (g === 'mr') return '0';
  if (g === 'ms') return '1';
  return '';
}

/** walk-in 接口要求 startTime/endTime 为 yyyy-MM-dd HH:mm；日期用当天（本地日历），时间与页面 HH:mm 一致 */
function toWalkInApiDateTime(hhmm) {
  if (hhmm == null || hhmm === '') return '';
  const parts = String(hhmm).trim().split(':');
  let h = parseInt(parts[0], 10);
  let m = parseInt(parts[1] ?? '0', 10);
  if (Number.isNaN(h)) h = 0;
  if (Number.isNaN(m)) m = 0;
  const hStr = String(Math.min(23, Math.max(0, h))).padStart(2, '0');
  const mStr = String(Math.min(59, Math.max(0, m))).padStart(2, '0');
  const d = new Date();
  const y = d.getFullYear();
  const mo = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  return `${y}-${mo}-${day} ${hStr}:${mStr}`;
}

async function handleConfirm() {
  if (!form.startTime || !form.endTime) {
    uni.showToast({ title: '请选择用餐时间', icon: 'none' });
    return;
  }
  if (!isEndAfterStartSameDay(form.endTime, form.startTime)) {
    uni.showToast({ title: END_AFTER_START_TIP, icon: 'none' });
    return;
  }
  const tableid = uni.getStorageSync('currentTableId') || '';
  const diners = uni.getStorageSync('currentDiners') ?? '1';
  if (!tableid) {
    uni.showToast({ title: '缺少桌台信息', icon: 'none' });
    return;
  }
  const phone = (form.phone || '').trim();
  if (!phone) {
    uni.showToast({ title: '请输入手机号', icon: 'none' });
    return;
  }
  const guestCount = parseInt(String(diners), 10);
  if (!Number.isFinite(guestCount) || guestCount < 1) {
    uni.showToast({ title: '就餐人数异常', icon: 'none' });
    return;
  }
  const tableIdNum = parseInt(String(tableid), 10);
  if (Number.isNaN(tableIdNum)) {
    uni.showToast({ title: '桌台信息异常', icon: 'none' });
    return;
  }

  const dto = {
    tableId: tableIdNum,
    guestCount,
    reservationUserPhone: phone,
    startTime: toWalkInApiDateTime(form.startTime),
    endTime: toWalkInApiDateTime(form.endTime)
  };
  const name = (form.name || '').trim();
  if (name) dto.reservationUserName = name;
  const genderCode = genderToReservationCode(form.gender);
  if (genderCode !== '') dto.reservationUserGender = genderCode;
  const remark = (form.remark || '').trim().slice(0, 30);
  if (remark) dto.remark = remark;

  try {
    await PostDiningWalkInReservation(dto);
  } catch {
    return;
  }

  uni.setStorageSync(
    'diningForm',
    JSON.stringify({
      startTime: form.startTime,
      endTime: form.endTime,
      endNextDay: true,
      name: form.name.trim(),
      gender: form.gender === 'mr' || form.gender === 'ms' ? form.gender : '',
      phone: form.phone.trim(),
      remark: (form.remark || '').trim()
    })
  );

  uni.redirectTo({
    url: `/pages/orderFood/index?tableid=${encodeURIComponent(String(tableid))}&diners=${encodeURIComponent(String(diners))}`
  });
}
</script>

<style lang="scss" scoped>
.page {
  min-height: 100vh;
  background: #f2f3f5;
  padding: 24rpx 30rpx 200rpx;
  box-sizing: border-box;
}

.card {
  background: #fff;
  border-radius: 20rpx;
  padding: 36rpx 30rpx 32rpx;
  box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.04);
}

.card-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #151515;
  margin-bottom: 28rpx;
  letter-spacing: 0.5rpx;
}

.section--time {
  padding-bottom: 8rpx;
}

/* 时间：「时间*」与「查看桌台信息」均靠左同一行 */
.time-label-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 8rpx 20rpx;
  margin-bottom: 20rpx;
}

.label {
  font-size: 28rpx;
  color: #333333;
  flex-shrink: 0;
  min-width: 100rpx;
}

.label--req::after {
  content: '*';
  color: #e61f19;
  margin-left: 2rpx;
}

.link {
  font-size: 26rpx;
  color: #ff7a2e;
  flex-shrink: 0;
}

.time-row {
  display: flex;
  flex-direction: row;
  gap: 20rpx;
}

.time-col {
  flex: 1;
  min-width: 0;
}

.time-picker {
  display: block;
  width: 100%;
}

.time-box {
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10rpx;
  padding: 22rpx 18rpx;
  background: #ffffff;
  border-radius: 8rpx;
  border: 1rpx solid #e8e8e8;
  min-height: 80rpx;
  box-sizing: border-box;
}

.time-box--readonly {
  pointer-events: none;
}

.time-clock {
  font-size: 30rpx;
  line-height: 1;
  flex-shrink: 0;
  opacity: 0.45;
}

.time-text {
  font-size: 26rpx;
  color: #333333;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.time-text.is-placeholder {
  color: #bbbbbb;
}

.divider {
  height: 1rpx;
  background: #eeeeee;
  margin: 0 -6rpx;
}

.row {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 24rpx;
  min-height: 100rpx;
  padding: 8rpx 0;
}

.row .label {
  width: 120rpx;
  min-width: 120rpx;
}

.row-gender {
  align-items: center;
}

.row-remark {
  align-items: flex-start;
  padding-top: 20rpx;
  padding-bottom: 12rpx;
}

.label-top {
  padding-top: 12rpx;
}

.input {
  flex: 1;
  min-width: 0;
  text-align:start;
  font-size: 28rpx;
  color: #333333;
  height: 72rpx;
  line-height: 72rpx;
}

.input-ph {
  color: #bbbbbb;
}

.gender-group {
  flex: 1;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  gap: 48rpx;
  min-width: 0;
}

.gender-opt {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 14rpx;
}

.gender-txt {
  font-size: 28rpx;
  color: #666666;
}

.gender-opt.active .gender-txt {
  color: #333333;
}

/* 未选：空心圆；已选：橙圈 + 内点 */
.gender-dot {
  width: 32rpx;
  height: 32rpx;
  border-radius: 50%;
  border: 2rpx solid #cccccc;
  box-sizing: border-box;
  flex-shrink: 0;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gender-dot.on {
  border-color: #fc743d;
}

.gender-dot-inner {
  width: 16rpx;
  height: 16rpx;
  border-radius: 50%;
  background: #fc743d;
}

.remark-wrap {
  flex: 1;
  min-width: 0;
  position: relative;
}

.textarea {
  width: 100%;
  min-height: 176rpx;
  padding: 20rpx 20rpx 48rpx 0;
  box-sizing: border-box;
  font-size: 28rpx;
  color: #333333;
  line-height: 1.5;
  background: #ffffff;
  border-radius: 8rpx;
  border: none;
}

.remark-count {
  position: absolute;
  right: 20rpx;
  bottom: 16rpx;
  font-size: 22rpx;
  color: #cccccc;
}

.footer-spacer {
  height: 24rpx;
}

.footer-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 24rpx 40rpx calc(24rpx + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, rgba(242, 243, 245, 0) 0%, #f2f3f5 28%);
  box-sizing: border-box;
  z-index: 100;
}

.footer-btn {
  height: 92rpx;
  line-height: 92rpx;
  text-align: center;
  font-size: 32rpx;
  font-weight: 500;
  color: #ffffff;
  border-radius: 46rpx;
  background: linear-gradient(90deg, #fcb73f 0%, #fc743d 100%);
  box-shadow: 0 8rpx 24rpx rgba(252, 116, 61, 0.35);
}

.footer-btn.hover-active:active {
  opacity: 0.92;
}

/* ========== 桌台信息底部弹窗 ========== */
.table-popup-root {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 1000;
  pointer-events: none;
}

.table-popup-mask {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  pointer-events: auto;
}

.table-popup-sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: #ffffff;
  border-radius: 24rpx 24rpx 0 0;
  padding: 28rpx 30rpx 0;
  box-sizing: border-box;
  max-height: 72vh;
  pointer-events: auto;
  box-shadow: 0 -8rpx 40rpx rgba(0, 0, 0, 0.12);
}

.table-popup-head {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 28rpx;
  border-bottom: 1rpx solid #f0f0f0;
}

.table-popup-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #151515;
}

.table-popup-close {
  width: 56rpx;
  height: 56rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: -8rpx;
}

.table-popup-close-x {
  font-size: 44rpx;
  color: #999999;
  line-height: 1;
  font-weight: 300;
}

.table-popup-close--active .table-popup-close-x,
.table-popup-close:active .table-popup-close-x {
  color: #666666;
}

.table-slot-grid {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  padding: 32rpx 0 8rpx;
  gap: 20rpx 16rpx;
}

.table-popup-hint {
  width: 100%;
  padding: 24rpx 0 40rpx;
  font-size: 28rpx;
  color: #666666;
  text-align: center;
}

.table-popup-hint--muted {
  color: #999999;
}

.table-slot-tag {
  width: calc((100% - 32rpx) / 3);
  box-sizing: border-box;
  padding: 22rpx 12rpx;
  background: #f5f5f5;
  border-radius: 12rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 72rpx;
}

.table-slot-tag-text {
  font-size: 26rpx;
  color: #666666;
  text-align: center;
  line-height: 1.35;
}

.table-popup-safe {
  height: calc(24rpx + env(safe-area-inset-bottom));
  min-height: 24rpx;
}
</style>
