<template>
  <div class="storage-cells-summary">
    <!-- 标题区域 -->
    <div class="summary-header">
      <span class="header-title">本区域空余暂存柜子</span>
      <div class="header-actions">
        <div class="back-btn" @click="handleBackToAddressSelect">
          <van-icon name="arrow-left" size="12px" />
          <span style="margin-left: 4px">重选地址</span>
        </div>
        <van-button v-if="!loading" size="small" type="primary" plain @click="refresh">
          刷新
        </van-button>
      </div>
    </div>

    <!-- 加载状态 -->
    <div v-if="loading" class="loading-state">
      <van-loading type="spinner" />
      <span class="loading-text">正在加载格口数据...</span>
    </div>

    <!-- 错误状态 -->
    <div v-else-if="error" class="error-state">
      <van-icon name="warning-o" size="48px" color="#F56C6C" />
      <span class="error-text">数据加载失败</span>
      <van-button size="small" type="primary" @click="refresh">重试</van-button>
    </div>

    <!-- 空状态 -->
    <div v-else-if="!hasAvailableCells" class="empty-state">
      <van-icon name="box" size="48px" color="#C0C4CC" />
      <span class="empty-text">暂无可用格口</span>
    </div>

    <!-- 格口类型选择区域 -->
    <div v-else class="cell-type-selection">
      <div class="cell-type-grid">
        <div
          v-for="stat in cellTypeStats"
          :key="stat.type"
          class="cell-type-card"
          :class="{
            'cell-type-card--selected': selectedCellType === stat.type,
            'cell-type-card--disabled': stat.count === 0
          }"
          @click="handleCellTypeSelect(stat)"
        >
          <div class="cell-type-icon">
            <img :src="getCellImg(stat.type)" class="product-image">
          </div>
          <span class="cell-type-name">{{ stat.name }}</span>
          <span class="cell-type-count">剩余{{ stat.count }}个可用</span>
        </div>
      </div>
    </div>

    <!-- 操作按钮区域 -->
    <div v-if="props.showButtons && hasAvailableCells && !loading" class="action-buttons">
      <van-row :gutter="16">
        <van-col :span="12">
          <van-button type="primary" block @click="handleDeposit"
            :loading="depositLoading"
            :disabled="depositLoading || retrieveLoading">
            物品暂存
          </van-button>
        </van-col>
        <van-col :span="12">
          <van-button type="success" block @click="handleRetrieve"
            :loading="retrieveLoading"
            :disabled="depositLoading || retrieveLoading">
            物品取出
          </van-button>
        </van-col>
      </van-row>
    </div>

    <!-- 弹窗组件 -->
    <van-popup
      v-model:show="popupVisible"
      position="bottom"
      round
      :style="popupStyle"
      @close="handlePopupCancel">

      <div class="popup-content" :style="popupContentStyle">
        <!-- 标题 -->
        <div class="popup-title">{{ popupTitle }}</div>

        <!-- 密码显示区域（仅在密码展示状态显示） -->
        <div v-if="currentState.type === 'password-show'" class="password-display-area">
          <div class="password-display-label">您的暂存密码</div>
          <div class="password-display-value">{{ currentState.password }}</div>
          <div class="password-display-hint">请务必牢记此密码</div>
        </div>

        <!-- 消息内容（密码展示状态不显示） -->
        <div v-if="currentState.type !== 'password-show'" class="popup-message">{{ popupMessage }}</div>

        <!-- 密码输入框 -->
        <van-password-input
          v-if="currentState.type === 'password-verify' || currentState.type === 'retrieve-input'"
          :value="popupInputValue"
          :length="passwordLength"
          :gutter="8"
          :mask="true"
          :focused="keyboardVisible"
          class="popup-password-input"
          @focus="keyboardVisible = true" />

        <!-- 处理中状态 -->
        <div v-if="currentState.type === 'processing'" class="processing-state">
          <van-loading type="spinner" />
          <span class="processing-text">
            {{ currentState.action === 'deposit' ? '正在存入...' : '正在取出...' }}
          </span>
        </div>

        <div class="popup-actions">
          <!-- 取消按钮 -->
          <van-button
            v-if="showCancelButton"
            type="default"
            block
            @click="handlePopupCancel">
            取消
          </van-button>

          <!-- 确认按钮 -->
          <van-button
            type="primary"
            block
            @click="handlePopupConfirm"
            :disabled="(currentState.type === 'password-verify' || currentState.type === 'retrieve-input') && popupInputValue.length !== passwordLength">
            {{ popupConfirmText }}
          </van-button>
        </div>

        <!-- 数字键盘 -->
        <van-number-keyboard
          v-model="popupInputValue"
          :show="keyboardVisible"
          :maxlength="passwordLength"
          theme="custom"
          close-button-text="完成"
          :safe-area-inset-bottom="true"
          @blur="handleKeyboardClose" />
      </div>
    </van-popup>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { showToast } from 'vant'
import {
  availableStorageCells,
  storeItemApi,
  openByPassword
} from '@/common/apis/cabinet'
import type { AvailableStorageCellDTO } from '@/common/apis/cabinet/type'
import { usePopupState } from '@/common/composables/usePopupState'
import { publicPath } from '@/common/utils/path'

// 格口类型映射
const CELL_TYPE_MAP = {
  1: '小格',
  2: '中格',
  3: '大格',
  4: '超大格'
} as const

// 组件 Props
interface Props {
  /** 店铺ID，用于获取可用格口列表 */
  shopId: number
  /** 是否自动加载数据 */
  autoLoad?: boolean
  /** 是否显示操作按钮 */
  showButtons?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  autoLoad: true,
  showButtons: true
})

// 组件 Emits
const emit = defineEmits<{
  (e: 'deposit'): void
  (e: 'retrieve'): void
  (e: 'refresh'): void
  (e: 'error', error: Error): void
  (e: 'backToAddressSelect'): void
}>()

// 状态变量
const loading = ref(false)
const error = ref<Error | null>(null)
const cellsData = ref<AvailableStorageCellDTO[]>([])
const selectedCellType = ref<number>(1)

const depositLoading = ref(false)
const retrieveLoading = ref(false)
const generatedPassword = ref('')

// 弹窗状态管理
const {
  currentState,
  popupInputValue,
  passwordLength,
  popupVisible,
  keyboardVisible,
  popupTitle,
  popupMessage,
  popupConfirmText,
  showCancelButton,
  transitionTo,
  handlePasswordInputChange,
  handlePopupCancel,
  handleKeyboardInput,
  handleKeyboardDelete,
  handleKeyboardClose
} = usePopupState()

// 弹窗样式计算属性
const popupStyle = computed(() => {
  const baseStyle = {
    padding: '32px',
    background: '#fff'
  }

  if (keyboardVisible.value) {
    return {
      ...baseStyle,
      maxHeight: 'calc(100vh - 360px)',
      overflow: 'auto'
    }
  }

  return {
    ...baseStyle,
    maxHeight: '80vh'
  }
})

const popupContentStyle = computed(() => {
  if (keyboardVisible.value) {
    return {
      paddingBottom: '160px'
    }
  }
  return {}
})

// 统计计算属性
const availableCells = computed(() =>
  cellsData.value.filter(cell => !cell.hasPassword)
)

const cellTypeStats = computed(() => {
  const stats = new Map<number, number>()

  availableCells.value.forEach(cell => {
    const type = cell.cellType
    stats.set(type, (stats.get(type) || 0) + 1)
  })

  // 确保所有四种类型都包含，即使数量为0
  const allTypes = [1, 2, 3, 4] as const
  return allTypes.map(type => ({
    type,
    name: CELL_TYPE_MAP[type as keyof typeof CELL_TYPE_MAP] || '未知',
    count: stats.get(type) || 0
  }))
})

const hasAvailableCells = computed(() =>
  availableCells.value.length > 0
)

// 数据获取逻辑
async function refresh() {
  loading.value = true
  error.value = null

  try {
    const response = await availableStorageCells(props.shopId)
    cellsData.value = response.data || []
    emit('refresh')
  } catch (err) {
    error.value = err as Error
    emit('error', err as Error)
    showToast({
      message: '数据加载失败',
      type: 'fail'
    })
  } finally {
    loading.value = false
  }
}

// 事件处理函数
function handleDeposit() {
  // 保持事件发射以向后兼容
  emit('deposit')
  // 调用新的存入流程函数
  handleDepositFlow()
}

function handleRetrieve() {
  // 保持事件发射以向后兼容
  emit('retrieve')
  // 调用新的取出流程函数
  handleRetrieveFlow()
}

function handleBackToAddressSelect() {
  emit('backToAddressSelect')
}

// 存入流程处理函数
async function handleDepositFlow() {
  try {
    depositLoading.value = true

    // 1. 分配格口
    const response = await storeItemApi({
      shopId: props.shopId,
      cellType: selectedCellType.value
    })

    const password = response.data?.password || ''
    if (!password) {
      throw new Error('格口分配失败，未获取到密码')
    }

    // 保存生成的密码以向后兼容
    generatedPassword.value = password

    // 2. 显示密码（状态转换）
    transitionTo({ type: 'password-show', password })

  } catch (err) {
    // 错误处理
    console.error('存入流程失败:', err)
    showToast({
      message: (err as any)?.message || '操作失败',
      type: 'fail',
      duration: 3000
    })
    transitionTo({ type: 'idle' })
  } finally {
    depositLoading.value = false
  }
}

// 弹窗相关事件处理
async function handlePopupConfirm() {
  const state = currentState.value

  switch (state.type) {
    case 'password-show':
      // 点击"已记住"，进入密码验证
      transitionTo({ type: 'password-verify', correctPassword: state.password })
      break

    case 'password-verify':
      // 验证密码
      if (popupInputValue.value !== state.correctPassword) {
        showToast({ message: '密码不正确', type: 'fail' })
        return
      }
      // 打开格口
      await performOpenByPassword(popupInputValue.value, 'deposit')
      break

    case 'retrieve-input':
      // 打开格口
      await performOpenByPassword(popupInputValue.value, 'retrieve')
      break
  }
}

async function performOpenByPassword(password: string, action: 'deposit' | 'retrieve') {
  transitionTo({ type: 'processing', action })

  try {
    await openByPassword({
      shopId: props.shopId,
      password: String(password)
    })

    showToast({
      message: '格口已打开',
      type: 'success'
    })

    // 刷新数据
    await refresh()
  } catch (err) {
    console.error('打开格口失败:', err)
    showToast({
      message: (err as any)?.message || '操作失败',
      type: 'fail',
      duration: 3000
    })
  } finally {
    transitionTo({ type: 'idle' })
  }
}

// 取出流程处理函数
function handleRetrieveFlow() {
  // 直接进入密码输入状态
  transitionTo({ type: 'retrieve-input' })
}

// 格口类型图标映射（需验证图标名称可用性）
const CELL_TYPE_ICON_MAP = {
  1: 'box',      // 小格
  2: 'archive',  // 中格
  3: 'package',  // 大格
  4: 'cube'      // 超大格
} as const

function getCellImg(type: number): string {
  // 假设图片放在 public/images/cabinet/ 目录下
  const basePath = publicPath + 'images/cabinet/'
  switch (type) {
    case 1: return `${basePath}small-cell.svg`
    case 2: return `${basePath}medium-cell.svg`
    case 3: return `${basePath}large-cell.svg`
    case 4: return `${basePath}extra-large-cell.svg`
    default: return `${basePath}small-cell.svg`
  }
}

// 处理格口类型选择
function handleCellTypeSelect(stat: { type: number; count: number }) {
  if (stat.count === 0) {
    showToast({
      message: '该类型格口暂不可用',
      type: 'fail',
      duration: 1500
    })
    return
  }
  selectedCellType.value = stat.type
}

// 生命周期钩子
onMounted(() => {
  if (props.autoLoad !== false) {
    refresh()
  }
})
</script>

<style scoped>
.storage-cells-summary {
  padding: 12px;
  background: #fff;
  border-radius: 24px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
}

.summary-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.header-title {
  font-size: 40px;
  font-weight: 600;
  color: #333;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 16px;  /* 原: 16rpx → 8px */
}

.back-btn {
  display: flex;
  align-items: center;
  padding: 8px 12px;  /* 原: 8rpx 12rpx → 4px 6px */
  background: #fff;
  border: 1px solid #e0e0e0;
  border-radius: 16px;  /* 原: 16rpx → 8px */
  font-size: 24px;  /* 原: 24rpx → 12px */
  color: #666;
  white-space: nowrap;
}

.back-btn:active {
  background: #f5f5f5;
}

.cell-type-selection {
  margin-bottom: 24px;
}

.cell-type-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
}

.cell-type-card {
  position: relative;
  padding: 40px 32px;
  background: #fff;
  border: 1px solid #e0e0e0;
  border-radius: 20px;
  text-align: center;
  transition: all 0.3s ease;
}

.cell-type-card:active:not(.cell-type-card--disabled) {
  transform: translateY(2px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.cell-type-card--selected {
  border-color: #2979ff;
  border-width: 2px;
  background: rgba(41, 121, 255, 0.04);
  box-shadow: 0 8px 32px rgba(41, 121, 255, 0.25);
}

.cell-type-card--selected .cell-type-name {
  color: #2979ff;
  font-weight: 500;
}

.cell-type-card--selected .cell-type-count {
  color: #2979ff;
}

.cell-type-card--disabled {
  background: #f9f9f9;
  border-color: #f0f0f0;
  opacity: 0.6;
}

.cell-type-card--disabled .cell-type-name,
.cell-type-card--disabled .cell-type-count {
  color: #ccc;
}

.cell-type-icon {
  margin-bottom: 20px;
}

.cell-type-name {
  display: block;
  font-size: 32px;
  font-weight: 400;
  color: #333;
  margin-bottom: 12px;
}

.cell-type-count {
  display: block;
  font-size: 28px;
  color: #666;
}

.product-image {
  width: 96px;
  height: 96px;
  border-radius: 4px;
}

.action-buttons {
  margin-top: 12px;

  .van-button {
    height: 52px;
    font-size: 20px;
    border-radius: 12px;
  }
}

/* 状态样式 */
.loading-state,
.error-state,
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 64px 0;  /* 原: 64rpx → 32px */
  text-align: center;
}

.loading-text,
.error-text,
.empty-text {
  margin-top: 24px;  /* 原: 24rpx → 12px */
  font-size: 28px;  /* 原: 28rpx → 14px */
  color: #666;
}

.error-state .error-text {
  color: #F56C6C;
  margin-bottom: 24px;  /* 原: 24rpx → 12px */
}

/* 弹窗样式 */
.popup-content {
  display: flex;
  flex-direction: column;
  gap: 32px;  /* 原: 32rpx → 16px */
}

.popup-title {
  font-size: 36px;  /* 原: 36rpx → 18px */
  font-weight: 600;
  color: #333;
  text-align: center;
}

.popup-message {
  font-size: 28px;  /* 原: 28rpx → 14px */
  color: #666;
  line-height: 1.5;
  white-space: pre-line;
  text-align: center;
}

.popup-password-input {
  margin: 32px 0;  /* 原: 32rpx → 16px */
}

.processing-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;  /* 原: 24rpx → 12px */
  padding: 48px 0;  /* 原: 48rpx → 24px */
}

.processing-text {
  font-size: 28px;  /* 原: 28rpx → 14px */
  color: #666;
}

.popup-actions {
  display: flex;
  gap: 16px;  /* 原: 16rpx → 8px */
  margin-top: 32px;  /* 原: 32rpx → 16px */
}

/* 密码显示区域样式 */
.password-display-area {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 48px 32px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 24px;
  margin: 16px 0;
}

.password-display-label {
  font-size: 28px;
  color: rgba(255, 255, 255, 0.85);
  margin-bottom: 20px;
}

.password-display-value {
  font-size: 72px;
  font-weight: 700;
  color: #fff;
  letter-spacing: 16px;
  line-height: 1.2;
  text-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.password-display-hint {
  font-size: 24px;
  color: rgba(255, 255, 255, 0.7);
  margin-top: 20px;
}

/* 注意：当前项目使用postcss-px-to-viewport插件，px单位会自动转换为vw */
/* 因此我们保持px单位，让插件自动处理移动端适配 */

</style>