<script setup lang="ts">
import type { Product, SupportFeedbackItem } from '~/types/site';
import { ApiError } from '~/composables/useRequest';

const { t, locale } = useI18n();
const { getProducts, submitSupportFeedback, getSupportFeedbacks } = useSiteApi();

const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const FEEDBACK_NO_RE = /^FB\d{8}[0-9A-Z]{6}$/i;
const MAX_LOG_SIZE = 20 * 1024 * 1024; // 与后端 multer limits 一致

// ===== 型号选项：来自产品列表（可见产品，按语言取名称） =====
const products = ref<Product[]>([]);
onMounted(async () => {
  try {
    const data = await getProducts();
    products.value = (data?.series || []).flatMap(s => s.products || []);
  } catch {
    products.value = [];
  }
});
const productOptions = computed(() =>
  products.value.map(p => ({ id: p.id, label: locale.value === 'en' ? p.name_en : p.name_zh }))
);

// ===== 提交表单状态 =====
const productId = ref('');
const description = ref('');
const email = ref('');
const logFile = ref<File | null>(null);
const fileInput = ref<HTMLInputElement | null>(null);
const errors = ref<Record<string, string>>({});
const submitting = ref(false);
const notice = ref<{ ok: boolean; text?: string; feedbackNo?: string } | null>(null);
const copiedNo = ref('');
const { copy, copied, isSupported } = useClipboard();

function onFileChange(e: Event) {
  const input = e.target as HTMLInputElement;
  const f = input.files?.[0] || null;
  if (f && f.size > MAX_LOG_SIZE) {
    notice.value = { ok: false, text: t('support.fileTooLarge') };
    logFile.value = null;
    input.value = '';
    return;
  }
  logFile.value = f;
}

function formatFileSize(size: number): string {
  if (size >= 1024 * 1024) return `${(size / 1024 / 1024).toFixed(1)} MB`;
  if (size >= 1024) return `${(size / 1024).toFixed(1)} KB`;
  return `${size} B`;
}

async function handleSubmit() {
  if (submitting.value) return;
  notice.value = null;

  const errs: Record<string, string> = {};
  if (!productId.value) errs.product = t('form.required');
  if (!description.value.trim()) errs.description = t('form.required');
  const emailTrim = email.value.trim();
  if (!emailTrim) errs.email = t('form.required');
  else if (!EMAIL_RE.test(emailTrim)) errs.email = t('form.invalidEmail');
  errors.value = errs;
  if (Object.keys(errs).length > 0) return;

  const fd = new FormData();
  fd.append('product_id', String(productId.value));
  fd.append('description', description.value.trim());
  fd.append('email', emailTrim);
  if (logFile.value) fd.append('log_file', logFile.value, logFile.value.name);

  submitting.value = true;
  try {
    const data = await submitSupportFeedback(fd);
    notice.value = { ok: true, feedbackNo: data?.feedback_no || '' };
    productId.value = '';
    description.value = '';
    email.value = '';
    logFile.value = null;
    if (fileInput.value) fileInput.value.value = '';
    // 查询区若已展示该邮箱的反馈，静默刷新
    if (queried.value && queryInput.value.trim().toLowerCase() === emailTrim.toLowerCase()) {
      loadFeedbacks({ email: emailTrim });
    }
  } catch (e) {
    notice.value = { ok: false, text: e instanceof ApiError ? e.message : t('support.feedbackFailed') };
  } finally {
    submitting.value = false;
  }
}

async function copyFeedbackNo(no: string) {
  if (!no) return;
  if (isSupported.value) {
    await copy(no);
    copiedNo.value = no;
  } else {
    try {
      await navigator.clipboard.writeText(no);
      copiedNo.value = no;
    } catch {
      /* ignore */
    }
  }
}

// ===== 我的反馈查询 =====
const queryInput = ref('');
const queryError = ref('');
const querying = ref(false);
const queried = ref(false);
const feedbacks = ref<SupportFeedbackItem[]>([]);
const lastQueryEmail = ref<string | null>(null);
const expandedFeedbackNo = ref<string | null>(null);
const verifiedEmails = ref<Record<string, string>>({});

function parseQueryInput(value: string): { email?: string; feedback_no?: string } | null {
  const trimmed = value.trim();
  if (!trimmed) return null;
  if (FEEDBACK_NO_RE.test(trimmed)) {
    return { feedback_no: trimmed.toUpperCase() };
  }
  if (EMAIL_RE.test(trimmed)) {
    return { email: trimmed };
  }
  return null;
}

async function loadFeedbacks(params: { email?: string; feedback_no?: string }) {
  try {
    const data = await getSupportFeedbacks(params);
    feedbacks.value = data?.items || [];
  } catch {
    feedbacks.value = [];
  }
}

async function handleQuery() {
  const value = queryInput.value.trim();
  if (!value || querying.value) return;

  const params = parseQueryInput(value);
  if (!params) {
    queryError.value = t('support.queryInvalid');
    queried.value = false;
    feedbacks.value = [];
    return;
  }

  queryError.value = '';
  querying.value = true;
  lastQueryEmail.value = params.email || null;
  expandedFeedbackNo.value = null;
  verifiedEmails.value = {};
  await loadFeedbacks(params);
  queried.value = true;
  querying.value = false;
}

function productName(item: SupportFeedbackItem): string {
  return locale.value === 'en' ? item.product_name_en : item.product_name_zh;
}

function statusLabel(status: string): string {
  if (status === 'processing') return t('support.statusProcessing');
  if (status === 'resolved') return t('support.statusResolved');
  return t('support.statusPending');
}

function statusMeta(status: string): { badge: string; accent: string; dot: string } {
  if (status === 'resolved') {
    return {
      badge: 'bg-emerald-50 text-emerald-700 ring-1 ring-emerald-200/80 dark:bg-emerald-950/40 dark:text-emerald-300 dark:ring-emerald-800/60',
      accent: 'bg-emerald-500',
      dot: 'bg-emerald-500',
    };
  }
  if (status === 'processing') {
    return {
      badge: 'bg-sky-50 text-sky-700 ring-1 ring-sky-200/80 dark:bg-sky-950/40 dark:text-sky-300 dark:ring-sky-800/60',
      accent: 'bg-sky-500',
      dot: 'bg-sky-500',
    };
  }
  return {
    badge: 'bg-amber-50 text-amber-700 ring-1 ring-amber-200/80 dark:bg-amber-950/40 dark:text-amber-300 dark:ring-amber-800/60',
    accent: 'bg-amber-500',
    dot: 'bg-amber-500',
  };
}

function isExpanded(item: SupportFeedbackItem): boolean {
  return expandedFeedbackNo.value === item.feedback_no;
}

function formatTime(iso: string): string {
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return '';
  const p = (n: number) => String(n).padStart(2, '0');
  return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;
}

function verifiedEmailFor(item: SupportFeedbackItem): string | null {
  if (verifiedEmails.value[item.feedback_no]) {
    return verifiedEmails.value[item.feedback_no];
  }
  if (lastQueryEmail.value) {
    return lastQueryEmail.value;
  }
  return null;
}

function toggleExpand(item: SupportFeedbackItem) {
  expandedFeedbackNo.value = expandedFeedbackNo.value === item.feedback_no ? null : item.feedback_no;
}

function handleEmailVerified(feedbackNo: string, email: string) {
  if (!email) {
    const next = { ...verifiedEmails.value };
    delete next[feedbackNo];
    verifiedEmails.value = next;
    return;
  }
  verifiedEmails.value = { ...verifiedEmails.value, [feedbackNo]: email };
}

function handleStatusUpdate(feedbackNo: string, status: string) {
  const item = feedbacks.value.find(f => f.feedback_no === feedbackNo);
  if (item && item.status !== status) {
    item.status = status;
  }
}
</script>

<template>
  <section>
    <h2 class="text-2xl md:text-3xl font-bold text-gray-900 dark:text-white mb-8px">{{ t('support.feedback') }}</h2>
    <p class="text-sm text-gray-500 dark:text-gray-400 mb-32px">{{ t('support.feedbackSubtitle') }}</p>

    <!-- 上下布局：上=提交表单，下=我的反馈；宽度与 contact 页一致 -->
    <div class="flex flex-col gap-32px mx-auto w-full">
      <!-- 提交表单 -->
      <form
        class="flex flex-col gap-20px p-24px rounded-12px border border-gray-100 dark:border-dark-700 bg-white dark:bg-dark-800"
        @submit.prevent="handleSubmit"
      >
        <div
          v-if="notice"
          class="px-16px py-12px rounded-8px text-sm leading-relaxed"
          :class="notice.ok
            ? 'bg-green-50 text-green-700 border border-green-200 dark:bg-green-900/20 dark:text-green-300 dark:border-green-800'
            : 'bg-red-50 text-red-600 border border-red-200 dark:bg-red-900/20 dark:text-red-300 dark:border-red-800'"
        >
          <template v-if="notice.ok && notice.feedbackNo">
            {{ t('support.feedbackSuccess') }}
            <button
              type="button"
              class="font-mono font-semibold underline underline-offset-2 hover:opacity-80 transition-opacity"
              :title="t('support.feedbackNoCopied')"
              @click="copyFeedbackNo(notice.feedbackNo)"
            >
              {{ notice.feedbackNo }}
            </button>
            <span v-if="copied && copiedNo === notice.feedbackNo" class="ml-8px text-xs opacity-80">
              {{ t('support.feedbackNoCopied') }}
            </span>
          </template>
          <template v-else>
            {{ notice.text }}
          </template>
        </div>

        <!-- 型号 -->
        <div class="flex flex-col gap-8px">
          <label class="text-sm font-medium text-gray-700 dark:text-gray-200">
            {{ t('support.model') }}
            <span class="text-red-500 ml-4px">*</span>
          </label>
          <select
            v-model="productId"
            class="px-16px py-12px rounded-8px border text-sm bg-white dark:bg-dark-800 dark:text-gray-100 outline-none transition-colors"
            :class="errors.product ? 'border-red-400' : 'border-gray-200 dark:border-dark-600 focus:border-primary'"
          >
            <option value="">{{ t('support.selectModel') }}</option>
            <option v-for="opt in productOptions" :key="opt.id" :value="opt.id">
              {{ opt.label }}
            </option>
          </select>
          <p v-if="errors.product" class="text-xs text-red-500">{{ errors.product }}</p>
        </div>

        <!-- 问题描述 -->
        <div class="flex flex-col gap-8px">
          <label class="text-sm font-medium text-gray-700 dark:text-gray-200">
            {{ t('support.description') }}
            <span class="text-red-500 ml-4px">*</span>
          </label>
          <textarea
            v-model="description"
            rows="5"
            maxlength="2000"
            :placeholder="t('support.descriptionPlaceholder')"
            class="px-16px py-12px rounded-8px border text-sm bg-white dark:bg-dark-800 dark:text-gray-100 outline-none transition-colors resize-y"
            :class="errors.description ? 'border-red-400' : 'border-gray-200 dark:border-dark-600 focus:border-primary'"
          ></textarea>
          <p v-if="errors.description" class="text-xs text-red-500">{{ errors.description }}</p>
        </div>

        <!-- 邮箱 -->
        <div class="flex flex-col gap-8px">
          <label class="text-sm font-medium text-gray-700 dark:text-gray-200">
            {{ t('support.email') }}
            <span class="text-red-500 ml-4px">*</span>
          </label>
          <input
            v-model="email"
            type="email"
            :placeholder="t('support.emailPlaceholder')"
            class="px-16px py-12px rounded-8px border text-sm bg-white dark:bg-dark-800 dark:text-gray-100 outline-none transition-colors"
            :class="errors.email ? 'border-red-400' : 'border-gray-200 dark:border-dark-600 focus:border-primary'"
          >
          <p v-if="errors.email" class="text-xs text-red-500">{{ errors.email }}</p>
        </div>

        <!-- 日志文件（可选） -->
        <div class="flex flex-col gap-8px">
          <label class="text-sm font-medium text-gray-700 dark:text-gray-200">{{ t('support.logFile') }}</label>
          <div class="flex items-center gap-12px">
            <input ref="fileInput" type="file" class="hidden" @change="onFileChange">
            <button
              type="button"
              class="px-20px py-10px rounded-8px border border-gray-200 dark:border-dark-600 text-sm text-gray-700 dark:text-gray-200 hover:border-primary hover:text-primary transition-colors"
              @click="fileInput?.click()"
            >
              {{ t('support.chooseFile') }}
            </button>
            <span v-if="logFile" class="text-xs text-gray-500 dark:text-gray-400 truncate">
              {{ logFile.name }}（{{ formatFileSize(logFile.size) }}）
            </span>
            <span v-else class="text-xs text-gray-400">{{ t('support.noFile') }}</span>
          </div>
        </div>

        <button
          type="submit"
          :disabled="submitting"
          class="mt-4px px-32px py-12px rounded-8px bg-primary text-white text-sm font-medium hover:opacity-90 transition-opacity disabled:opacity-50 disabled:cursor-not-allowed self-center"
        >
          {{ submitting ? t('common.loading') : t('support.submitFeedback') }}
        </button>
      </form>

      <!-- 我的反馈查询 -->
      <div class="feedback-panel flex flex-col gap-20px p-24px md:p-28px rounded-16px border border-gray-200/80 dark:border-dark-600/80 bg-white dark:bg-dark-800 shadow-sm">
        <div class="flex flex-col gap-6px">
          <h3 class="text-lg md:text-xl font-semibold text-gray-900 dark:text-white tracking-tight">
            {{ t('support.myFeedback') }}
          </h3>
          <p class="text-sm text-gray-500 dark:text-gray-400">
            {{ t('support.queryPlaceholder') }}
          </p>
        </div>

        <div class="flex flex-col sm:flex-row gap-10px">
          <div class="relative flex-1 min-w-0">
            <span class="feedback-search-icon pointer-events-none absolute left-14px top-1/2 -translate-y-1/2 text-gray-400 dark:text-gray-500" aria-hidden="true">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-18px h-18px">
                <path fill-rule="evenodd" d="M9 3.5a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11ZM2 9a7 7 0 1 1 12.452 4.391l3.328 3.329a.75.75 0 1 1-1.06 1.06l-3.329-3.328A7 7 0 0 1 2 9Z" clip-rule="evenodd" />
              </svg>
            </span>
            <input
              v-model="queryInput"
              type="text"
              :placeholder="t('support.queryPlaceholder')"
              class="feedback-search-input w-full pl-42px pr-16px py-13px rounded-12px border text-sm bg-gray-50/80 dark:bg-dark-900/50 dark:text-gray-100 outline-none transition-all placeholder:text-gray-400 dark:placeholder:text-gray-500"
              :class="queryError
                ? 'border-red-400 focus:border-red-400 focus:ring-2 focus:ring-red-400/20'
                : 'border-gray-200 dark:border-dark-600 focus:border-primary focus:ring-2 focus:ring-primary/15'"
              @keyup.enter="handleQuery"
              @input="queryError = ''"
            >
          </div>
          <button
            type="button"
            :disabled="querying"
            class="feedback-query-btn shrink-0 px-28px py-13px rounded-12px bg-primary text-white text-sm font-medium shadow-sm hover:shadow-md hover:opacity-95 active:scale-[0.98] transition-all disabled:opacity-50 disabled:cursor-not-allowed"
            @click="handleQuery"
          >
            {{ querying ? t('common.loading') : t('support.query') }}
          </button>
        </div>

        <p v-if="queryError" class="text-xs text-red-500 -mt-8px">{{ queryError }}</p>

        <div
          v-if="queried && !querying && feedbacks.length === 0"
          class="feedback-empty flex flex-col items-center justify-center gap-12px py-48px px-24px rounded-12px border border-dashed border-gray-200 dark:border-dark-600 bg-gray-50/50 dark:bg-dark-900/30"
        >
          <div class="w-48px h-48px rounded-full bg-gray-100 dark:bg-dark-700 flex items-center justify-center text-gray-400">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="w-24px h-24px">
              <path stroke-linecap="round" stroke-linejoin="round" d="M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 0 1-.825-.242m9.345-8.334a2.126 2.126 0 0 0-.476-.095 48.64 48.64 0 0 0-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0 0 11.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155" />
            </svg>
          </div>
          <p class="text-sm text-gray-500 dark:text-gray-400">{{ t('support.noFeedback') }}</p>
        </div>

        <div v-else-if="feedbacks.length > 0" class="flex flex-col gap-14px">
          <article
            v-for="item in feedbacks"
            :key="item.id"
            class="feedback-card group relative overflow-hidden rounded-14px border transition-all duration-200"
            :class="isExpanded(item)
              ? 'border-primary/40 dark:border-primary/30 bg-white dark:bg-dark-800 shadow-md ring-1 ring-primary/10'
              : 'border-gray-200/90 dark:border-dark-600/80 bg-white dark:bg-dark-800/90 hover:border-gray-300 dark:hover:border-dark-500 hover:shadow-sm'"
          >
            <span
              class="feedback-card-accent absolute left-0 top-0 bottom-0 w-3px"
              :class="statusMeta(item.status).accent"
              aria-hidden="true"
            />

            <div class="p-18px md:p-20px pl-22px md:pl-24px flex flex-col gap-14px">
              <div class="flex items-start justify-between gap-16px">
                <div class="min-w-0 flex-1">
                  <div class="flex items-center gap-10px mb-8px">
                    <span class="feedback-product-icon shrink-0 w-36px h-36px rounded-10px bg-primary/10 text-primary flex items-center justify-center">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-18px h-18px">
                        <path fill-rule="evenodd" d="M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-7-4a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM9 9a.75.75 0 0 0 0 1.5h.253a.25.25 0 0 1 .244.304l-.459 2.066A1.75 1.75 0 0 0 10.747 15H11a.75.75 0 0 0 0-1.5h-.253a.25.25 0 0 1-.244-.304l.459-2.066A1.75 1.75 0 0 0 9.253 9H9Z" clip-rule="evenodd" />
                      </svg>
                    </span>
                    <h4 class="font-semibold text-base text-gray-900 dark:text-white truncate">
                      {{ productName(item) }}
                    </h4>
                  </div>

                  <div class="flex flex-wrap items-center gap-x-10px gap-y-6px text-xs text-gray-500 dark:text-gray-400">
                    <time>{{ formatTime(item.created_at) }}</time>
                    <template v-if="item.feedback_no">
                      <span class="text-gray-300 dark:text-gray-600">|</span>
                      <button
                        type="button"
                        class="feedback-no-chip inline-flex items-center gap-6px font-mono text-primary hover:text-primary/80 transition-colors"
                        :title="t('support.feedbackNoCopied')"
                        @click="copyFeedbackNo(item.feedback_no)"
                      >
                        {{ item.feedback_no }}
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-14px h-14px shrink-0 text-primary">
                          <path d="M7 3.5A1.5 1.5 0 0 1 8.5 2h3.879a1.5 1.5 0 0 1 1.06.44l3.122 3.12A1.5 1.5 0 0 1 17 6.622V12.5a1.5 1.5 0 0 1-1.5 1.5h-1v-3.379a3 3 0 0 0-.879-2.121L10.5 5.379A3 3 0 0 0 8.379 4.5H7v-1Z" />
                          <path d="M4.5 6A1.5 1.5 0 0 0 3 7.5v9A1.5 1.5 0 0 0 4.5 18h7a1.5 1.5 0 0 0 1.5-1.5v-5.879a1.5 1.5 0 0 0-.44-1.06L9.44 6.439A1.5 1.5 0 0 0 8.378 6H4.5Z" />
                        </svg>
                      </button>
                      <span
                        v-if="copied && copiedNo === item.feedback_no"
                        class="text-emerald-600 dark:text-emerald-400"
                      >
                        {{ t('support.feedbackNoCopied') }}
                      </span>
                    </template>
                  </div>
                </div>

                <span
                  class="feedback-status shrink-0 inline-flex items-center gap-6px px-10px py-4px rounded-full text-xs font-medium"
                  :class="statusMeta(item.status).badge"
                >
                  <span class="w-6px h-6px rounded-full" :class="statusMeta(item.status).dot" />
                  {{ statusLabel(item.status) }}
                </span>
              </div>

              <div class="rounded-10px bg-gray-50/90 dark:bg-dark-900/45 px-14px py-12px border border-gray-100/80 dark:border-dark-600/60 flex items-start gap-12px">
                <p
                  class="flex-1 min-w-0 text-sm text-gray-700 dark:text-gray-300 leading-relaxed whitespace-pre-line break-words"
                  :class="isExpanded(item) ? '' : 'line-clamp-2'"
                >
                  {{ item.description }}
                </p>
                <button
                  type="button"
                  class="feedback-toggle-btn shrink-0 self-center inline-flex items-center gap-4px px-12px py-7px rounded-8px text-xs font-medium transition-all"
                  :class="isExpanded(item)
                    ? 'bg-primary/10 text-primary'
                    : 'bg-white text-gray-700 ring-1 ring-gray-200/90 hover:bg-primary/10 hover:text-primary hover:ring-primary/20 dark:bg-dark-700 dark:text-gray-200 dark:ring-dark-500 dark:hover:bg-primary/15 dark:hover:text-primary'"
                  @click="toggleExpand(item)"
                >
                  {{ isExpanded(item) ? t('support.collapseChat') : t('support.expandChat') }}
                  <svg
                    xmlns="http://www.w3.org/2000/svg"
                    viewBox="0 0 20 20"
                    fill="currentColor"
                    class="w-14px h-14px transition-transform duration-200"
                    :class="isExpanded(item) ? 'rotate-180' : ''"
                  >
                    <path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 0 1 1.06.02L10 11.168l3.71-3.94a.75.75 0 1 1 1.08 1.04l-4.25 4.5a.75.75 0 0 1-1.08 0l-4.25-4.5a.75.75 0 0 1 .02-1.06Z" clip-rule="evenodd" />
                  </svg>
                </button>
              </div>

              <a
                v-if="item.log_file_path"
                :href="item.log_file_path"
                target="_blank"
                rel="noopener noreferrer"
                class="feedback-attachment inline-flex items-center gap-6px max-w-full self-start px-10px py-6px rounded-8px text-xs text-gray-600 dark:text-gray-300 bg-gray-100/80 dark:bg-dark-700/80 hover:bg-gray-200/80 dark:hover:bg-dark-600/80 transition-colors truncate"
                @click.stop
              >
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-14px h-14px shrink-0 text-gray-400">
                  <path fill-rule="evenodd" d="m15.988 3.012-8.25 8.25a2.25 2.25 0 1 1-3.182-3.182l8.25-8.25a3.75 3.75 0 0 1 5.303 5.303l-8.25 8.25a5.25 5.25 0 1 1-7.424-7.424l8.25-8.25a.75.75 0 1 1 1.06 1.06l-8.25 8.25a3.75 3.75 0 0 0 5.303 5.303l8.25-8.25a2.25 2.25 0 0 0-3.182-3.182l-8.25 8.25a.75.75 0 1 1-1.06-1.06l8.25-8.25a3.75 3.75 0 0 0-5.303-5.303Z" clip-rule="evenodd" />
                </svg>
                <span class="truncate">{{ item.log_file_name }}</span>
              </a>

              <SupportFeedbackChat
                v-if="isExpanded(item)"
                :item="item"
                :verified-email="verifiedEmailFor(item)"
                @verified="(email) => handleEmailVerified(item.feedback_no, email)"
                @status-update="(status) => handleStatusUpdate(item.feedback_no, status)"
              />
            </div>
          </article>
        </div>
      </div>
    </div>
  </section>
</template>

<style scoped>
.feedback-panel {
  background-image: linear-gradient(180deg, rgb(255 255 255 / 1) 0%, rgb(249 250 251 / 0.55) 100%);
}

:root.dark .feedback-panel,
.dark .feedback-panel {
  background-image: linear-gradient(180deg, rgb(30 30 35 / 1) 0%, rgb(24 24 28 / 0.92) 100%);
}

.feedback-card-accent {
  opacity: 0.92;
}

.feedback-no-chip:focus-visible,
.feedback-toggle-btn:focus-visible,
.feedback-query-btn:focus-visible,
.feedback-search-input:focus-visible {
  outline: none;
}
</style>
