<template>
  <ElDialog
    :model-value="open"
    append-to-body
    width="420px"
    :show-close="false"
    :close-on-click-modal="!busy"
    :close-on-press-escape="!busy"
    class="operation-feedback-dialog"
    modal-class="operation-feedback-overlay"
    @update:model-value="handleModelUpdate"
    @closed="resetForm"
  >
    <section class="operation-feedback">
      <header class="operation-feedback-head">
        <span class="operation-feedback-icon">
          <i class="mdi mdi-message-star-outline"></i>
        </span>
        <div>
          <h3>评价本轮处理</h3>
          <p>请给本轮智能体处理结果打分。</p>
        </div>
      </header>

      <div class="operation-feedback-stars" role="radiogroup" aria-label="本轮处理评分">
        <button
          v-for="score in scores"
          :key="score"
          type="button"
          class="operation-feedback-star"
          :class="{ active: score <= rating }"
          :disabled="busy"
          :aria-checked="rating === score ? 'true' : 'false'"
          role="radio"
          @click="rating = score"
          @mouseenter="hoverRating = score"
          @mouseleave="hoverRating = 0"
        >
          <i :class="score <= displayRating ? 'mdi mdi-star' : 'mdi mdi-star-outline'"></i>
        </button>
      </div>

      <Transition name="feedback-reason-slide">
        <label v-if="showReasonInput" class="operation-feedback-reason">
          <span>不满意的原因</span>
          <textarea
            v-model="reason"
            maxlength="500"
            rows="3"
            :disabled="busy"
            placeholder="例如：意图识别不准、信息提取遗漏、流程引导不清晰..."
          ></textarea>
          <small>{{ reason.length }}/500</small>
        </label>
      </Transition>

      <p v-if="errorMessage" class="operation-feedback-error">{{ errorMessage }}</p>

      <footer class="operation-feedback-actions">
        <button type="button" class="operation-feedback-secondary" :disabled="busy" @click="emit('close')">
          稍后评价
        </button>
        <button
          type="button"
          class="operation-feedback-primary"
          :disabled="busy || !rating"
          @click="submit"
        >
          <i v-if="busy" class="mdi mdi-loading mdi-spin"></i>
          <span>{{ busy ? '提交中...' : '提交评价' }}</span>
        </button>
      </footer>
    </section>
  </ElDialog>
</template>

<script setup>
import { computed, ref, watch } from 'vue'
import { ElDialog } from 'element-plus/es/components/dialog/index.mjs'

const props = defineProps({
  open: { type: Boolean, default: false },
  busy: { type: Boolean, default: false },
  errorMessage: { type: String, default: '' }
})

const emit = defineEmits(['close', 'submit'])
const scores = [1, 2, 3, 4, 5]
const rating = ref(0)
const hoverRating = ref(0)
const reason = ref('')
const displayRating = computed(() => hoverRating.value || rating.value)
const showReasonInput = computed(() => rating.value > 0 && rating.value <= 3)

function resetForm() {
  rating.value = 0
  hoverRating.value = 0
  reason.value = ''
}

function handleModelUpdate(value) {
  if (!value) {
    emit('close')
  }
}

function submit() {
  emit('submit', {
    rating: rating.value,
    reason: reason.value
  })
}

watch(
  () => props.open,
  (open) => {
    if (open) {
      resetForm()
    }
  }
)
</script>

<style scoped>
:deep(.operation-feedback-dialog) {
  border-radius: 8px;
}

:deep(.operation-feedback-dialog .el-dialog__header) {
  display: none;
}

:deep(.operation-feedback-dialog .el-dialog__body) {
  padding: 20px;
}

.operation-feedback {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 2px 2px 0;
}

.operation-feedback-head {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}

.operation-feedback-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 6px;
  background: #eef4ff;
  color: #1d4ed8;
  font-size: 20px;
}

.operation-feedback h3 {
  margin: 0;
  color: #172033;
  font-size: 17px;
  font-weight: 700;
}

.operation-feedback p {
  margin: 5px 0 0;
  color: #667085;
  font-size: 13px;
  line-height: 1.6;
}

.operation-feedback-stars {
  display: flex;
  justify-content: center;
  gap: 8px;
  padding: 6px 0 2px;
}

.operation-feedback-star {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border: 1px solid #d6deea;
  border-radius: 6px;
  background: #fff;
  color: #9aa8bb;
  cursor: pointer;
  font-size: 24px;
  transition: border-color 180ms ease, color 180ms ease, background 180ms ease;
}

.operation-feedback-star:hover,
.operation-feedback-star.active {
  border-color: #f59e0b;
  background: #fff7ed;
  color: #f59e0b;
}

.operation-feedback-star:disabled {
  cursor: not-allowed;
  opacity: 0.7;
}

.operation-feedback-reason {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.operation-feedback-reason span {
  color: #344054;
  font-size: 13px;
  font-weight: 600;
}

.operation-feedback-reason textarea {
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
  min-height: 82px;
  border: 1px solid #d0d5dd;
  border-radius: 6px;
  padding: 10px 12px;
  color: #172033;
  font: inherit;
  line-height: 1.5;
  outline: none;
  transition: border-color 180ms ease, box-shadow 180ms ease;
}

.operation-feedback-reason textarea:focus {
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgb(37 99 235 / 12%);
}

.operation-feedback-reason small {
  align-self: flex-end;
  color: #98a2b3;
  font-size: 12px;
}

.operation-feedback-error {
  margin: 0;
  color: #b42318;
  font-size: 13px;
}

.operation-feedback-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.operation-feedback-secondary,
.operation-feedback-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 88px;
  height: 34px;
  border-radius: 6px;
  border: 1px solid #d0d5dd;
  padding: 0 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.operation-feedback-secondary {
  background: #fff;
  color: #344054;
}

.operation-feedback-primary {
  border-color: #2563eb;
  background: #2563eb;
  color: #fff;
}

.operation-feedback-secondary:disabled,
.operation-feedback-primary:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.feedback-reason-slide-enter-active,
.feedback-reason-slide-leave-active {
  transition: opacity 180ms ease, transform 180ms ease;
}

.feedback-reason-slide-enter-from,
.feedback-reason-slide-leave-to {
  opacity: 0;
  transform: translateY(-6px);
}
</style>
