<template>
  <el-dialog
    :visible.sync="dialogVisible"
    title="发布确认"
    width="900px"
    :before-close="handleCancel"
    class="xt-diff-publish-dialog"
    :close-on-click-modal="false"
    :close-on-press-escape="true"
    top="5vh"
  >
    <!-- 对话框头部 -->
    <template slot="title">
      <div class="dialog-header">
        <div class="header-title">
          <i class="el-icon-upload2 header-icon"></i>
          <span>发布确认</span>
          <el-tag size="small" type="warning" v-if="totalChanges > 0">
            {{ totalChanges }} 项变更
          </el-tag>
        </div>
      </div>
    </template>

    <!-- 对话框内容 -->
    <div class="dialog-content">
      <!-- 操作工具栏 -->
      <div class="toolbar">
        <div class="toolbar-left">
          <el-input
            v-model="searchKeyword"
            placeholder="搜索字段名..."
            size="small"
            prefix-icon="el-icon-search"
            clearable
            class="search-input"
          />
          
          <el-button-group class="filter-buttons">
            <el-button
              size="small"
              :type="showOnlyChanged ? 'primary' : ''"
              @click="showOnlyChanged = !showOnlyChanged"
              icon="el-icon-view"
            >
              只看变更
            </el-button>
          </el-button-group>
        </div>

        <div class="toolbar-right">
          <el-button
            size="small"
            @click="handleSelectAll"
            :disabled="filteredDiffs.length === 0"
          >
            {{ isAllSelected ? '取消全选' : '全选' }}
          </el-button>
          
          <span class="selection-count">
            已选择 {{ selectedKeys.length }} / {{ filteredDiffs.length }} 项
          </span>
        </div>
      </div>

      <!-- 差异对比列表 -->
      <div class="diff-list" v-loading="loading">
        <div
          v-for="diff in filteredDiffs"
          :key="diff.key"
          class="diff-item"
          :class="{ 
            'is-selected': selectedKeys.includes(diff.key),
            'is-changed': diff.isChanged,
            'is-new': diff.isNew,
            'is-deleted': diff.isDeleted
          }"
        >
          <!-- 选择框和字段信息 -->
          <div class="diff-header">
            <el-checkbox
              v-model="selectedKeys"
              :label="diff.key"
              :disabled="!diff.isChanged && !diff.isNew && !diff.isDeleted"
            >
              <div class="field-info">
                <span class="field-name">{{ diff.name || diff.key }}</span>
                <div class="field-meta">
                  <el-tag 
                    size="mini" 
                    :type="getChangeTypeTag(diff).type"
                    :icon="getChangeTypeTag(diff).icon"
                  >
                    {{ getChangeTypeTag(diff).text }}
                  </el-tag>
                  <span class="field-path" v-if="diff.path">{{ diff.path }}</span>
                </div>
              </div>
            </el-checkbox>
          </div>

          <!-- 值对比 -->
          <div class="diff-content" v-if="diff.isChanged || diff.isNew || diff.isDeleted">
            <div class="value-comparison">
              <!-- 原值 -->
              <div class="value-section original" v-if="!diff.isNew">
                <div class="value-label">原值</div>
                <div class="value-content">
                  <pre class="value-text">{{ formatValue(diff.oldValue) }}</pre>
                </div>
              </div>

              <!-- 箭头分隔符 -->
              <div class="value-separator" v-if="diff.isChanged">
                <i class="el-icon-right separator-icon"></i>
              </div>

              <!-- 新值 -->
              <div class="value-section new" v-if="!diff.isDeleted">
                <div class="value-label">新值</div>
                <div class="value-content">
                  <pre class="value-text">{{ formatValue(diff.newValue) }}</pre>
                </div>
              </div>
            </div>

            <!-- 变更说明 -->
            <div class="change-description" v-if="diff.description">
              <i class="el-icon-info"></i>
              <span>{{ diff.description }}</span>
            </div>
          </div>
        </div>

        <!-- 空状态 -->
        <div class="empty-state" v-if="filteredDiffs.length === 0 && !loading">
          <div class="empty-icon">
            <i class="el-icon-document-copy"></i>
          </div>
          <div class="empty-text">
            <p class="empty-title">{{ searchKeyword ? '未找到匹配的字段' : '暂无变更内容' }}</p>
            <p class="empty-desc">
              {{ searchKeyword ? '请尝试其他搜索关键词' : '当前配置与线上版本一致' }}
            </p>
          </div>
        </div>
      </div>
    </div>

    <!-- 对话框底部 -->
    <template slot="footer">
      <div class="dialog-footer">
        <div class="footer-info">
          <span class="publish-info" v-if="selectedKeys.length > 0">
            即将发布 <strong>{{ selectedKeys.length }}</strong> 项配置变更
          </span>
        </div>
        <div class="footer-actions">
          <el-button @click="handleCancel" size="medium">
            取消
          </el-button>
          <el-button
            type="primary"
            @click="handleConfirm"
            size="medium"
            :disabled="selectedKeys.length === 0"
            :loading="publishing"
          >
            <i class="el-icon-upload2" v-if="!publishing"></i>
            {{ publishing ? '发布中...' : '确认发布' }}
          </el-button>
        </div>
      </div>
    </template>
  </el-dialog>
</template>

<script>
export default {
  name: 'XtDiffPublishDialog',
  
  props: {
    // 是否显示对话框
    visible: {
      type: Boolean,
      default: false
    },
    
    // 差异数据
    diffs: {
      type: Array,
      default: () => []
      // 格式: { key, name, path, oldValue, newValue, isChanged, isNew, isDeleted, description }
    },
    
    // 加载状态
    loading: {
      type: Boolean,
      default: false
    },
    
    // 发布状态
    publishing: {
      type: Boolean,
      default: false
    }
  },

  data() {
    return {
      searchKeyword: '',
      showOnlyChanged: false,
      selectedKeys: []
    }
  },

  computed: {
    dialogVisible: {
      get() {
        return this.visible
      },
      set(value) {
        if (!value) {
          this.handleCancel()
        }
      }
    },

    // 总变更数
    totalChanges() {
      return this.diffs.filter(diff => diff.isChanged || diff.isNew || diff.isDeleted).length
    },

    // 过滤后的差异列表
    filteredDiffs() {
      let filtered = this.diffs

      // 搜索过滤
      if (this.searchKeyword.trim()) {
        const keyword = this.searchKeyword.toLowerCase()
        filtered = filtered.filter(diff => 
          (diff.name || diff.key).toLowerCase().includes(keyword) ||
          (diff.path || '').toLowerCase().includes(keyword)
        )
      }

      // 只看变更过滤
      if (this.showOnlyChanged) {
        filtered = filtered.filter(diff => diff.isChanged || diff.isNew || diff.isDeleted)
      }

      return filtered
    },

    // 是否全选
    isAllSelected() {
      const selectableDiffs = this.filteredDiffs.filter(diff => 
        diff.isChanged || diff.isNew || diff.isDeleted
      )
      return selectableDiffs.length > 0 && 
             selectableDiffs.every(diff => this.selectedKeys.includes(diff.key))
    }
  },

  watch: {
    visible(newVal) {
      if (newVal) {
        // 对话框打开时，默认选中所有变更项
        this.selectedKeys = this.diffs
          .filter(diff => diff.isChanged || diff.isNew || diff.isDeleted)
          .map(diff => diff.key)
      } else {
        // 对话框关闭时重置状态
        this.resetState()
      }
    }
  },

  methods: {
    handleConfirm() {
      if (this.selectedKeys.length === 0) {
        this.$message.warning('请至少选择一项要发布的配置')
        return
      }

      this.$emit('confirm', this.selectedKeys)
    },

    handleCancel() {
      this.$emit('cancel')
    },

    handleSelectAll() {
      const selectableDiffs = this.filteredDiffs.filter(diff => 
        diff.isChanged || diff.isNew || diff.isDeleted
      )
      
      if (this.isAllSelected) {
        // 取消全选
        selectableDiffs.forEach(diff => {
          const index = this.selectedKeys.indexOf(diff.key)
          if (index > -1) {
            this.selectedKeys.splice(index, 1)
          }
        })
      } else {
        // 全选
        selectableDiffs.forEach(diff => {
          if (!this.selectedKeys.includes(diff.key)) {
            this.selectedKeys.push(diff.key)
          }
        })
      }
    },

    // 获取变更类型标签
    getChangeTypeTag(diff) {
      if (diff.isNew) {
        return { type: 'success', icon: 'el-icon-plus', text: '新增' }
      } else if (diff.isDeleted) {
        return { type: 'danger', icon: 'el-icon-minus', text: '删除' }
      } else if (diff.isChanged) {
        return { type: 'warning', icon: 'el-icon-edit', text: '修改' }
      } else {
        return { type: 'info', icon: 'el-icon-minus', text: '无变更' }
      }
    },

    // 格式化值显示
    formatValue(value) {
      if (value === null || value === undefined) {
        return '(空)'
      }
      
      if (typeof value === 'object') {
        return JSON.stringify(value, null, 2)
      }
      
      return String(value)
    },

    // 重置状态
    resetState() {
      this.searchKeyword = ''
      this.showOnlyChanged = false
      this.selectedKeys = []
    }
  }
}
</script>

<style lang="scss" scoped>
.xt-diff-publish-dialog {
  ::v-deep .el-dialog {
    background: var(--color-bg-card);
    border-radius: var(--radius-2xl);
    box-shadow: var(--shadow-2xl);
    max-height: 90vh;
    display: flex;
    flex-direction: column;
  }

  ::v-deep .el-dialog__header {
    background: var(--color-bg-card);
    border-bottom: 1px solid var(--color-border-primary);
    border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
    padding: var(--spacing-5) var(--spacing-6);

    .dialog-header {
      .header-title {
        display: flex;
        align-items: center;
        gap: var(--spacing-2);
        color: var(--color-text-primary);
        font-size: var(--font-size-lg);
        font-weight: var(--font-weight-semibold);

        .header-icon {
          color: var(--color-primary);
          font-size: var(--font-size-xl);
        }
      }
    }
  }

  ::v-deep .el-dialog__body {
    background: var(--color-bg-card);
    padding: 0;
    flex: 1;
    overflow: hidden;
  }

  ::v-deep .el-dialog__footer {
    background: var(--color-bg-card);
    border-top: 1px solid var(--color-border-primary);
    border-radius: 0 0 var(--radius-2xl) var(--radius-2xl);
    padding: var(--spacing-4) var(--spacing-6);
  }

  .dialog-content {
    display: flex;
    flex-direction: column;
    height: 60vh;
    max-height: 600px;

    .toolbar {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: var(--spacing-4) var(--spacing-6);
      background: var(--color-bg-secondary);
      border-bottom: 1px solid var(--color-border-primary);
      gap: var(--spacing-4);

      .toolbar-left {
        display: flex;
        align-items: center;
        gap: var(--spacing-3);
        flex: 1;

        .search-input {
          width: 240px;

          ::v-deep .el-input__inner {
            background: var(--color-bg-card);
            border-radius: var(--radius-lg);
          }
        }

        .filter-buttons {
          ::v-deep .el-button {
            border-radius: var(--radius-md);
            font-weight: var(--font-weight-medium);
          }
        }
      }

      .toolbar-right {
        display: flex;
        align-items: center;
        gap: var(--spacing-3);

        .selection-count {
          font-size: var(--font-size-sm);
          color: var(--color-text-tertiary);
          font-weight: var(--font-weight-medium);
        }
      }
    }

    .diff-list {
      flex: 1;
      overflow-y: auto;
      padding: var(--spacing-4) var(--spacing-6);

      .diff-item {
        background: var(--color-bg-card);
        border: 1px solid var(--color-border-primary);
        border-radius: var(--radius-lg);
        margin-bottom: var(--spacing-4);
        transition: all var(--duration-200) var(--ease-out);

        &:hover {
          box-shadow: var(--shadow-sm);
          transform: translateY(-1px);
        }

        &.is-selected {
          border-color: var(--color-primary);
          box-shadow: 0 0 0 1px var(--color-primary-100);
        }

        &.is-changed {
          border-left: 4px solid var(--color-warning);
        }

        &.is-new {
          border-left: 4px solid var(--color-success);
        }

        &.is-deleted {
          border-left: 4px solid var(--color-danger);
          opacity: 0.8;
        }

        .diff-header {
          padding: var(--spacing-4);
          border-bottom: 1px solid var(--color-border-secondary);

          ::v-deep .el-checkbox {
            width: 100%;

            .el-checkbox__label {
              width: 100%;
              padding-left: var(--spacing-2);
            }
          }

          .field-info {
            .field-name {
              color: var(--color-text-primary);
              font-weight: var(--font-weight-medium);
              font-size: var(--font-size-base);
              display: block;
              margin-bottom: var(--spacing-1);
            }

            .field-meta {
              display: flex;
              align-items: center;
              gap: var(--spacing-2);

              .field-path {
                color: var(--color-text-tertiary);
                font-size: var(--font-size-sm);
                font-family: var(--font-family-mono);
              }
            }
          }
        }

        .diff-content {
          padding: var(--spacing-4);

          .value-comparison {
            display: flex;
            gap: var(--spacing-4);
            align-items: flex-start;
            margin-bottom: var(--spacing-3);

            .value-section {
              flex: 1;
              min-width: 0;

              .value-label {
                color: var(--color-text-tertiary);
                font-size: var(--font-size-sm);
                font-weight: var(--font-weight-medium);
                margin-bottom: var(--spacing-2);
              }

              .value-content {
                background: var(--color-bg-tertiary);
                border-radius: var(--radius-md);
                padding: var(--spacing-3);
                border: 1px solid var(--color-border-secondary);

                .value-text {
                  color: var(--color-text-primary);
                  font-family: var(--font-family-mono);
                  font-size: var(--font-size-sm);
                  line-height: var(--line-height-relaxed);
                  margin: 0;
                  white-space: pre-wrap;
                  word-break: break-all;
                  max-height: 120px;
                  overflow-y: auto;
                }
              }

              &.original .value-content {
                background: var(--color-danger-50);
                border-color: var(--color-danger-200);
              }

              &.new .value-content {
                background: var(--color-success-50);
                border-color: var(--color-success-200);
              }
            }

            .value-separator {
              display: flex;
              align-items: center;
              justify-content: center;
              padding-top: 28px;

              .separator-icon {
                color: var(--color-text-tertiary);
                font-size: var(--font-size-lg);
              }
            }
          }

          .change-description {
            display: flex;
            align-items: flex-start;
            gap: var(--spacing-2);
            padding: var(--spacing-3);
            background: var(--color-primary-50);
            border-radius: var(--radius-md);
            font-size: var(--font-size-sm);
            color: var(--color-primary-dark);

            i {
              color: var(--color-primary);
              margin-top: 2px;
              flex-shrink: 0;
            }
          }
        }
      }

      .empty-state {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: var(--spacing-12);
        text-align: center;

        .empty-icon {
          font-size: 64px;
          color: var(--color-text-quaternary);
          margin-bottom: var(--spacing-4);
        }

        .empty-text {
          .empty-title {
            color: var(--color-text-secondary);
            font-size: var(--font-size-lg);
            font-weight: var(--font-weight-medium);
            margin: 0 0 var(--spacing-2) 0;
          }

          .empty-desc {
            color: var(--color-text-tertiary);
            font-size: var(--font-size-sm);
            margin: 0;
          }
        }
      }
    }
  }

  .dialog-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .footer-info {
      .publish-info {
        color: var(--color-text-secondary);
        font-size: var(--font-size-sm);

        strong {
          color: var(--color-primary);
          font-weight: var(--font-weight-semibold);
        }
      }
    }

    .footer-actions {
      display: flex;
      gap: var(--spacing-3);

      .el-button {
        border-radius: var(--radius-lg);
        font-weight: var(--font-weight-medium);
        padding: var(--spacing-2) var(--spacing-5);

        &[type="primary"]:not(:disabled) {
          &:hover {
            transform: translateY(-1px);
            box-shadow: var(--shadow-md);
          }
        }
      }
    }
  }
}

// 响应式设计
@media (max-width: 768px) {
  .xt-diff-publish-dialog {
    ::v-deep .el-dialog {
      width: 95% !important;
      margin: 0 auto;
    }

    .dialog-content {
      height: 70vh;

      .toolbar {
        flex-direction: column;
        align-items: stretch;
        gap: var(--spacing-3);

        .toolbar-left {
          flex-direction: column;
          align-items: stretch;

          .search-input {
            width: 100%;
          }
        }

        .toolbar-right {
          justify-content: space-between;
        }
      }

      .diff-list {
        .diff-item {
          .diff-content {
            .value-comparison {
              flex-direction: column;

              .value-separator {
                padding: var(--spacing-2) 0;
                
                .separator-icon {
                  transform: rotate(90deg);
                }
              }
            }
          }
        }
      }
    }

    .dialog-footer {
      flex-direction: column;
      align-items: stretch;
      gap: var(--spacing-3);

      .footer-actions {
        justify-content: flex-end;
      }
    }
  }
}
</style>
