<script setup lang="ts">
/**
 * 文件职责：复制配置到其他门店弹窗。
 * 1. 展示可选目标门店列表。
 * 2. 处理全选/单选交互并向父级抛事件。
 * 3. 仅做 UI 交互，不执行复制请求。
 */
import type { StoreListItemDto } from '#/api/store';

import { computed } from 'vue';

import { Button, Empty, Modal } from 'ant-design-vue';

interface Props {
  confirmText?: string;
  copyCandidates: StoreListItemDto[];
  isAllChecked: boolean;
  isIndeterminate: boolean;
  isSubmitting: boolean;
  open: boolean;
  selectedStoreName: string;
  targetStoreIds: string[];
  title?: string;
  warningText?: string;
}

const props = withDefaults(defineProps<Props>(), {
  confirmText: '确认复制',
  title: '复制配置到其他门店',
  warningText: '将覆盖目标门店的现有设置，请谨慎操作',
});

const emit = defineEmits<{
  (event: 'checkAll', checked: boolean): void;
  (event: 'submit'): void;
  (event: 'toggleStore', payload: { checked: boolean; storeId: string }): void;
  (event: 'update:open', value: boolean): void;
}>();

const selectedStoreIdSet = computed(() => new Set(props.targetStoreIds));
const hasCandidates = computed(() => props.copyCandidates.length > 0);

/** 判断目标门店是否被选中。 */
function isStoreChecked(storeId: string) {
  return selectedStoreIdSet.value.has(storeId);
}

/** 切换单个门店选中态并通知父级。 */
function toggleStore(storeId: string) {
  emit('toggleStore', {
    storeId,
    checked: !isStoreChecked(storeId),
  });
}

/** 切换全选状态并通知父级。 */
function toggleAll() {
  emit('checkAll', !props.isAllChecked);
}
</script>

<template>
  <Modal
    :open="props.open"
    :title="props.title"
    :width="650"
    :footer="null"
    :mask-closable="true"
    wrap-class-name="store-copy-modal-wrap"
    @update:open="(value) => emit('update:open', value)"
  >
    <div class="store-copy-modal-content">
      <div class="store-copy-modal-source">
        当前门店：{{ props.selectedStoreName || '--' }}
      </div>
      <div class="store-copy-modal-warning">
        <span class="store-copy-modal-warning-icon">!</span>
        <span>{{ props.warningText }}</span>
      </div>

      <template v-if="hasCandidates">
        <div class="store-copy-all-row" @click="toggleAll">
          <span
            class="store-copy-check"
            :class="{
              checked: props.isAllChecked,
              indeterminate: props.isIndeterminate && !props.isAllChecked,
            }"
          >
            <span class="store-copy-check-mark"></span>
          </span>
          <span>全选</span>
        </div>

        <div class="store-copy-list">
          <div
            v-for="store in props.copyCandidates"
            :key="store.id"
            class="store-copy-item"
            @click="toggleStore(store.id)"
          >
            <span
              class="store-copy-check"
              :class="{ checked: isStoreChecked(store.id) }"
            >
              <span class="store-copy-check-mark"></span>
            </span>
            <div class="store-copy-info">
              <div class="store-copy-name">{{ store.name }}</div>
              <div class="store-copy-address">{{ store.address || '--' }}</div>
            </div>
          </div>
        </div>
      </template>

      <div v-else class="store-copy-empty">
        <Empty description="暂无可复制的门店" />
      </div>
    </div>
    <div class="store-copy-modal-footer">
      <Button @click="emit('update:open', false)">取消</Button>
      <Button
        type="primary"
        :loading="props.isSubmitting"
        :disabled="props.targetStoreIds.length === 0"
        @click="emit('submit')"
      >
        {{ props.confirmText }}
      </Button>
    </div>
  </Modal>
</template>

<style lang="less">
/* 文件职责：复制配置弹窗（Teleport）全局样式。 */
.store-copy-modal-wrap {
  .ant-modal {
    width: 650px !important;
    max-width: calc(100vw - 32px);
  }

  .ant-modal-content {
    overflow: hidden;
    padding: 0;
    border-radius: 14px;
    box-shadow: 0 10px 30px rgb(0 0 0 / 12%);
  }

  .ant-modal-header {
    margin-bottom: 0;
    padding: 20px 28px 14px;
    border-bottom: 1px solid #f0f0f0;
  }

  .ant-modal-title {
    font-size: 16px;
    font-weight: 600;
    color: #1f2329;
  }

  .ant-modal-close {
    top: 18px;
    right: 20px;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    color: #8f959e;
    transition: all 0.2s ease;
  }

  .ant-modal-close:hover {
    color: #4e5969;
    background: #f2f3f5;
  }

  .ant-modal-body {
    padding: 0;
  }
}

.store-copy-modal-content {
  padding: 18px 28px 0;
}

.store-copy-modal-source {
  margin-bottom: 10px;
  font-size: 13px;
  color: #4e5969;
}

.store-copy-modal-warning {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 18px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 500;
  color: #c48b26;
  background: #fffbe6;
  border: 1px solid #f7e4a1;
  border-radius: 10px;
}

.store-copy-modal-warning-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  background: #f5b034;
  border-radius: 50%;
}

.store-copy-all-row {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 0 0 12px;
  font-size: 13px;
  font-weight: 500;
  color: #1f2329;
  cursor: pointer;
}

.store-copy-list {
  max-height: 340px;
  padding-top: 12px;
  overflow-y: auto;
  border-top: 1px solid #f0f0f0;
}

.store-copy-item {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-bottom: 10px;
  padding: 12px 12px 10px;
  background: #fafbfc;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.store-copy-item:hover {
  background: #f3f6fb;
}

.store-copy-info {
  flex: 1;
  min-width: 0;
}

.store-copy-name {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.4;
  color: #1f2329;
}

.store-copy-address {
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.5;
  color: #86909c;
}

.store-copy-check {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  background: #fff;
  border: 1px solid #d9dde3;
  border-radius: 5px;
  transition: all 0.2s ease;
}

.store-copy-check-mark {
  display: none;
  width: 6px;
  height: 10px;
  border: 2px solid #fff;
  border-top: 0;
  border-left: 0;
  transform: rotate(45deg) translate(-1px, -1px);
}

.store-copy-check.checked {
  background: #1677ff;
  border-color: #1677ff;
}

.store-copy-check.checked .store-copy-check-mark {
  display: block;
}

.store-copy-check.indeterminate {
  background: #1677ff;
  border-color: #1677ff;
}

.store-copy-check.indeterminate .store-copy-check-mark {
  display: block;
  width: 10px;
  height: 2px;
  border: 0;
  background: #fff;
  transform: none;
}

.store-copy-empty {
  padding: 20px 0;
}

.store-copy-modal-footer {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
  padding: 14px 28px 18px;
  margin-top: 10px;
  border-top: 1px solid #f0f0f0;
}
</style>
