<template>
  <div class="app-container template-editor-page">
    <!-- 顶部标题栏 -->
    <div class="editor-page-header">
      <div class="header-left">
        <div class="page-title">{{ isEdit ? '编辑模板' : '新增模板' }}</div>
        <div class="page-desc">左侧选择组件，中间预览，右侧操作组件顺序</div>
      </div>

      <div class="header-right">
        <el-button size="mini" @click="goBack">返回</el-button>
        <el-button size="mini" type="primary" @click="submitForm">保存模板</el-button>
      </div>
    </div>

    <!-- 顶部表单区域 -->
    <div class="template-base-form">
      <el-form :model="form" label-width="90px" size="small">
        <el-row :gutter="16">
          <el-col :span="8">
            <el-form-item label="模板名称">
              <el-input v-model="form.templateName" placeholder="请输入模板名称" />
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item label="模板类型" prop="templateType">
               <el-radio-group v-model="form.templateType">
                   <el-radio label="home">首页模板</el-radio>
                   <el-radio label="user">个人中心模板</el-radio>
               </el-radio-group>
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item label="模板封面">
              <el-input v-model="form.coverUrl" placeholder="请输入模板封面地址" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="16">
          <el-col :span="8">
            <el-form-item label="状态">
              <el-radio-group v-model="form.status">
                <el-radio :label="1">启用</el-radio>
                <el-radio :label="0">停用</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>

          <el-col :span="16">
            <el-form-item label="备注">
              <el-input v-model="form.remark" placeholder="请输入备注" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>

    <!-- 编辑器主体 -->
    <div class="editor-main">
      <!-- 左侧组件库 -->
      <div class="component-library">
        <div class="panel-title">组件库</div>

        <el-select
          v-model="componentQuery.componentTypeCode"
          placeholder="组件类型"
          clearable
          size="mini"
          style="width: 100%; margin-bottom: 10px;"
          @change="loadComponentList"
        >
          <el-option
            v-for="item in typeOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>

        <div class="component-card-list">
          <div
            v-for="item in componentList"
            :key="item.id"
            class="component-card"
            :class="{ disabled: usedComponentCodes.includes(item.componentCode) }"
            @click="addComponent(item)"
          >
            <img
              v-if="item.previewImage"
              :src="item.previewImage"
              class="component-thumb"
            />
            <div v-else class="component-thumb icon-thumb">
              <i :class="item.icon || 'el-icon-picture'"></i>
            </div>
            <div class="component-name">{{ item.componentName }}</div>
          </div>
        </div>
      </div>

      <!-- 中间手机画布 -->
      <div class="canvas-panel">
        <div class="panel-title">页面画布（手机预览）</div>

        <div class="phone-frame modern-phone">
          <div class="phone-status-bar modern-status-bar">
            <span class="status-time">9:41</span>
            <div class="status-icons">
              <span class="signal-bars">
                <i></i><i></i><i></i><i></i>
              </span>
              <span class="wifi-icon">◜◝</span>
              <span class="battery-icon">
                <span class="battery-body"></span>
                <span class="battery-cap"></span>
              </span>
            </div>
          </div>

          <div class="phone-screen modern-phone-screen">
              <draggable
                  v-model="form.components"
                  class="canvas-list"
                  animation="200"
                  :move="checkMove"
                  @end="normalizeComponentsOrder"
              >
              <transition-group>
                <div
                  v-for="(item, index) in form.components"
                  :key="item.id"
                  class="canvas-item"
                  :class="{ active: selectedIndex === index }"
                  @click.stop="selectComponent(index)"
                >
                  <component
                    :is="getPreviewComponent(item.componentCode)"
                    class="preview-runtime"
                  />
                </div>
              </transition-group>
            </draggable>

            <div v-if="!form.components.length" class="empty-tip">
              请从左侧点击组件添加到页面
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧组件操作 -->
      <div class="config-panel">
        <div class="panel-title">组件操作</div>

        <div v-if="selectedComponent" class="config-box">
          <div class="config-row">
            <span class="label">组件编码：</span>
            <span class="value">{{ selectedComponent.componentCode }}</span>
          </div>

          <div class="config-row">
            <span class="label">当前位置：</span>
            <span class="value">第 {{ selectedIndex + 1 }} 个</span>
          </div>

          <div class="config-actions">
              <el-button
                  size="mini"
                  @click="moveUp"
                  :disabled="
                    selectedIndex <= 0 ||
                    selectedComponent.componentCode === 'Banner' ||
                    selectedComponent.componentCode === 'RecommendedProducts'"
              >
                  上移
              </el-button>
              <el-button
                  size="mini"
                  @click="moveDown"
                  :disabled="
                    selectedIndex >= form.components.length - 1 ||
                    selectedComponent.componentCode === 'Banner' ||
                    selectedComponent.componentCode === 'RecommendedProducts'"
              >
                  下移
              </el-button>

            <el-button
              size="mini"
              type="danger"
              @click="removeSelected"
            >
              删除组件
            </el-button>
          </div>
        </div>

        <div v-else class="config-empty">
          请点击中间画布中的组件
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import draggable from 'vuedraggable'
import {
  getDecorationTemplate,
  saveDecorationTemplate,
  listDecorationComponent,
  listComponentTypeOptions
} from '@/api/decoration/decoration'

import BannerPreview from '@/components/decoration/BannerPreview.vue'
import NoticeBarPreview from '@/components/decoration/NoticeBarPreview.vue'
import GoodsListPreview from '@/components/decoration/GoodsListPreview.vue'
import CouponCardPreview from '@/components/decoration/CouponCardPreview.vue'
import BrandStoryPreview from '@/components/decoration/BrandStoryPreview.vue'
import BottomCtaPreview from '@/components/decoration/BottomCtaPreview.vue'

export default {
  name: 'DecorationTemplateEditor',
  components: {
    draggable
  },
  data() {
    return {
      selectedIndex: -1,
      typeOptions: [],
      componentList: [],
      componentQuery: {
        componentTypeCode: '',
        status: 1
      },
      form: {
        id: null,
        templateName: '',
        templateType: 'home',
        coverUrl: '',
        status: 1,
        remark: '',
        components: []
      }
    }
  },
  computed: {
    isEdit() {
        return !!this.$route.query.id
    },
    selectedComponent() {
        if (this.selectedIndex < 0) return null
        return this.form.components[this.selectedIndex] || null
    },
    usedComponentCodes() {
        return this.form.components.map(item => item.componentCode)
    }
  },
  created() {
    this.loadTypeOptions()
    this.loadComponentList()
    this.loadDetail()
  },
  methods: {
    goBack() {
      this.$router.push('/decoration/template/list')
    },

    loadTypeOptions() {
      listComponentTypeOptions().then(res => {
        this.typeOptions = res.data || []
      })
    },

    loadComponentList() {
      listDecorationComponent(this.componentQuery).then(res => {
        this.componentList = res.data || []
      })
    },

    loadDetail() {
      const id = this.$route.query.id
      if (!id) return

      getDecorationTemplate(id).then(res => {
        const data = res.data || {}
        const templateData = JSON.parse(data.templateData || '{}')

        this.form = {
          id: data.id,
          templateName: data.templateName,
          templateType: data.templateType,
          coverUrl: data.coverUrl,
          status: data.status,
          remark: data.remark,
          components: templateData.components || []
        }
      })
    },

    selectComponent(index) {
      this.selectedIndex = index
    },

    removeSelected() {
      if (this.selectedIndex < 0) return
      this.form.components.splice(this.selectedIndex, 1)
      this.selectedIndex = -1
    },


    getPreviewComponent(code) {
      const map = {
        Banner: BannerPreview,
        MenuBar: NoticeBarPreview,
        FlashSale: GoodsListPreview,
        TodayGroupDeals: CouponCardPreview,
        LimitedTimeDiscount: BrandStoryPreview,
        TrendingList: BottomCtaPreview,
        RecommendedProducts: GoodsListPreview
      }
      return map[code] || BannerPreview
    },

    isFixedTop(componentCode) {
      return componentCode === 'Banner'
    },

    isFixedBottom(componentCode) {
      return componentCode === 'RecommendedProducts'
    },

    addComponent(item) {
      // 每个组件只能添加一次
      if (this.usedComponentCodes.includes(item.componentCode)) {
          this.$message.warning('该组件已经添加过了，不能重复添加')
          return
      }

      this.form.components.push({
          id: 'cmp_' + Date.now() + '_' + Math.floor(Math.random() * 10000),
          componentCode: item.componentCode,
          props: {}
      })

      this.normalizeComponentsOrder()
    },

    normalizeComponentsOrder() {
      const oldSelected = this.selectedComponent ? this.selectedComponent.id : null

      const list = this.form.components || []

      const topList = []
      const middleList = []
      const bottomList = []

      list.forEach(item => {
          if (this.isFixedTop(item.componentCode)) {
              topList.push(item)
          } else if (this.isFixedBottom(item.componentCode)) {
              bottomList.push(item)
          } else {
              middleList.push(item)
          }
      })

      this.form.components = topList.concat(middleList, bottomList)

      if (oldSelected) {
          this.selectedIndex = this.form.components.findIndex(item => item.id === oldSelected)
      }
    },

    checkMove(evt) {
      const dragged = evt.draggedContext && evt.draggedContext.element
      const related = evt.relatedContext && evt.relatedContext.element

      if (!dragged) return true

      // Banner 不允许被拖动到非顶部
      if (this.isFixedTop(dragged.componentCode)) {
          return false
      }

      // RecommendedProducts 不允许被拖动到非底部
      if (this.isFixedBottom(dragged.componentCode)) {
          return false
      }

      // 其他组件不能拖到 Banner 上面
      if (related && this.isFixedTop(related.componentCode)) {
          return false
      }

      // 其他组件不能拖到 RecommendedProducts 下面
      if (related && this.isFixedBottom(related.componentCode)) {
          return false
      }

      return true
    },

    moveUp() {
      if (this.selectedIndex <= 0) return

      const current = this.form.components[this.selectedIndex]
      const prev = this.form.components[this.selectedIndex - 1]

      if (this.isFixedTop(current.componentCode)) {
          this.$message.warning('轮播图必须在最上面')
          return
      }

      if (prev && this.isFixedTop(prev.componentCode)) {
          this.$message.warning('不能移动到轮播图上方')
          return
      }

      const arr = this.form.components
      this.$set(arr, this.selectedIndex, prev)
      this.$set(arr, this.selectedIndex - 1, current)
      this.selectedIndex = this.selectedIndex - 1

      this.normalizeComponentsOrder()
    },

    moveDown() {
      if (this.selectedIndex < 0 || this.selectedIndex >= this.form.components.length - 1) return

      const current = this.form.components[this.selectedIndex]
      const next = this.form.components[this.selectedIndex + 1]

      if (this.isFixedBottom(current.componentCode)) {
          this.$message.warning('推荐商品必须在最下面')
          return
      }

      if (next && this.isFixedBottom(next.componentCode)) {
          this.$message.warning('不能移动到推荐商品下方')
          return
      }

      const arr = this.form.components
      this.$set(arr, this.selectedIndex, next)
      this.$set(arr, this.selectedIndex + 1, current)
      this.selectedIndex = this.selectedIndex + 1

      this.normalizeComponentsOrder()
    },

    submitForm() {
      // 保存前再兜底整理一次顺序
      this.normalizeComponentsOrder()

      const payload = {
          id: this.form.id,
          templateName: this.form.templateName,
          templateType: this.form.templateType,
          coverUrl: this.form.coverUrl,
          status: this.form.status,
          remark: this.form.remark,
          templateData: JSON.stringify({
              pageConfig: {
                  templateName: this.form.templateName
              },
              components: this.form.components
          })
      }

      saveDecorationTemplate(payload).then(() => {
          this.$message.success('保存成功')
          this.goBack()
      })
    }
  }
}
</script>

<style scoped>
.template-editor-page {
  height: calc(100vh - 84px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* 页面顶部 */
.editor-page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  flex-shrink: 0;
}

.page-title {
  font-size: 20px;
  font-weight: 600;
  color: #303133;
}

.page-desc {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}

/* 顶部表单 */
.template-base-form {
  background: #fff;
  padding: 16px 16px 2px;
  border-radius: 8px;
  margin-bottom: 16px;
  flex-shrink: 0;
}

/* 主体三栏 */
.editor-main {
  flex: 1;
  display: flex;
  gap: 16px;
  min-height: 0;
  overflow: hidden;
}

/* 左侧组件库 */
.component-library {
  width: 280px;
  border: 1px solid #ebeef5;
  padding: 12px;
  overflow-y: auto;
  background: #fff;
  border-radius: 8px;
  flex-shrink: 0;
}

/* 中间画布 */
.canvas-panel {
  flex: 1;
  padding: 12px;
  background: #f5f7fa;
  overflow: auto;
  min-width: 0;
  border-radius: 8px;
}

/* 右侧操作区 */
.config-panel {
  width: 240px;
  border: 1px solid #ebeef5;
  padding: 12px;
  background: #fff;
  overflow-y: auto;
  border-radius: 8px;
  flex-shrink: 0;
}

.panel-title {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 12px;
}

/* 左侧组件卡片 */
.component-card-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.component-card {
  width: calc(50% - 5px);
  border: 1px solid #dcdfe6;
  border-radius: 6px;
  padding: 8px;
  cursor: pointer;
  background: #fff;
  transition: all 0.2s;
}

.component-card:hover {
  border-color: #409EFF;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
}

.component-thumb {
  width: 100%;
  height: 70px;
  object-fit: cover;
  border-radius: 4px;
}

.icon-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  background: #f5f7fa;
}

.component-name {
  margin-top: 8px;
  text-align: center;
  font-size: 13px;
}

/* 手机 */
.phone-frame.modern-phone {
  width: 370px;
  height: 760px;
  margin: 0 auto;
  background: #0f0f10;
  border-radius: 42px;
  padding: 10px;
  box-sizing: border-box;
  box-shadow:
    0 18px 40px rgba(0, 0, 0, 0.18),
    0 2px 8px rgba(0, 0, 0, 0.08);
  position: relative;
  border: 2px solid #1b1b1d;
}

.modern-status-bar {
  height: 28px;
  padding: 0 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #111;
  font-size: 12px;
  font-weight: 600;
  background: #fff;
  border-top-left-radius: 32px;
  border-top-right-radius: 32px;
  box-sizing: border-box;
}

.status-time {
  color: #222;
  font-size: 12px;
  font-weight: 600;
}

.status-icons {
  display: flex;
  align-items: center;
  gap: 8px;
}

.signal-bars {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 12px;
}

.signal-bars i {
  display: block;
  width: 2px;
  background: #222;
  border-radius: 1px;
}

.signal-bars i:nth-child(1) { height: 4px; }
.signal-bars i:nth-child(2) { height: 6px; }
.signal-bars i:nth-child(3) { height: 8px; }
.signal-bars i:nth-child(4) { height: 10px; }

.wifi-icon {
  font-size: 10px;
  color: #222;
  line-height: 1;
}

.battery-icon {
  display: flex;
  align-items: center;
  gap: 2px;
}

.battery-body {
  width: 18px;
  height: 9px;
  border: 1.5px solid #222;
  border-radius: 2px;
  position: relative;
  display: inline-block;
}

.battery-body::after {
  content: '';
  position: absolute;
  left: 1px;
  top: 1px;
  width: 11px;
  height: 5px;
  background: #9adf7f;
  border-radius: 1px;
}

.battery-cap {
  width: 2px;
  height: 5px;
  background: #222;
  border-radius: 1px;
  display: inline-block;
}

.modern-phone-screen {
  height: calc(100% - 28px);
  background: #fff;
  border-bottom-left-radius: 32px;
  border-bottom-right-radius: 32px;
  overflow-y: auto;
  padding: 10px 10px 14px;
  box-sizing: border-box;
}

.modern-phone-screen::-webkit-scrollbar {
  width: 4px;
}

.modern-phone-screen::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.15);
  border-radius: 2px;
}

/* 画布组件 */
.canvas-list {
  min-height: 200px;
}

.canvas-item {
  background: #fff;
  border: 1px solid #ebeef5;
  border-radius: 12px;
  padding: 10px;
  margin-bottom: 10px;
  cursor: move;
  transition: all 0.2s;
}

.canvas-item:hover {
  border-color: #409EFF;
  box-shadow: 0 2px 10px rgba(64, 158, 255, 0.12);
}

.canvas-item.active {
  border-color: #409EFF;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.12);
}

.preview-runtime {
  width: 100%;
}

.empty-tip {
  text-align: center;
  color: #909399;
  padding: 40px 0;
}

/* 右侧操作面板 */
.config-box {
  border: 1px solid #ebeef5;
  border-radius: 8px;
  padding: 12px;
  background: #fafafa;
}

.config-row {
  margin-bottom: 12px;
  line-height: 20px;
}

.config-row .label {
  color: #909399;
}

.config-row .value {
  color: #303133;
  word-break: break-all;
}

.config-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.config-empty {
  color: #909399;
  text-align: center;
  padding: 40px 10px;
}

.component-card.disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.component-card.disabled:hover {
    border-color: #dcdfe6;
    box-shadow: none;
}
</style>
