<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 statusClass(status: string): string {
  if (status === 'resolved') return 'bg-green-50 text-green-700 border-green-200 dark:bg-green-900/20 dark:text-green-300 dark:border-green-800';
  if (status === 'processing') return 'bg-blue-50 text-blue-700 border-blue-200 dark:bg-blue-900/20 dark:text-blue-300 dark:border-blue-800';
  return 'bg-amber-50 text-amber-700 border-amber-200 dark:bg-amber-900/20 dark:text-amber-300 dark:border-amber-800';
}

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="flex flex-col gap-16px p-24px rounded-12px border border-gray-100 dark:border-dark-700 bg-white dark:bg-dark-800">
        <h3 class="text-lg font-semibold text-gray-900 dark:text-white">{{ t('support.myFeedback') }}</h3>

        <div class="flex gap-8px">
          <input
            v-model="queryInput"
            type="text"
            :placeholder="t('support.queryPlaceholder')"
            class="flex-1 min-w-0 px-16px py-12px rounded-8px border text-sm bg-white dark:bg-dark-800 dark:text-gray-100 outline-none transition-colors focus:border-primary"
            :class="queryError ? 'border-red-400' : 'border-gray-200 dark:border-dark-600'"
            @keyup.enter="handleQuery"
            @input="queryError = ''"
          >
          <button
            type="button"
            :disabled="querying"
            class="px-24px py-12px rounded-8px bg-primary text-white text-sm font-medium hover:opacity-90 transition-opacity disabled:opacity-50 self-start"
            @click="handleQuery"
          >
            {{ querying ? t('common.loading') : t('support.query') }}
          </button>
        </div>

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

        <div v-if="queried && !querying && feedbacks.length === 0" class="py-32px text-center text-sm text-gray-400">
          {{ t('support.noFeedback') }}
        </div>

        <div v-else class="flex flex-col gap-12px">
          <div
            v-for="item in feedbacks"
            :key="item.id"
            class="flex flex-col gap-8px p-16px rounded-8px border border-gray-100 dark:border-dark-700 bg-gray-50/50 dark:bg-dark-700/40"
          >
            <button
              type="button"
              class="flex flex-col gap-8px text-left w-full"
              @click="toggleExpand(item)"
            >
              <div class="flex items-center justify-between gap-12px">
                <span class="font-medium text-sm text-gray-900 dark:text-white truncate">{{ productName(item) }}</span>
                <span class="shrink-0 px-10px py-2px rounded-full border text-xs" :class="statusClass(item.status)">
                  {{ statusLabel(item.status) }}
                </span>
              </div>
              <div class="flex items-center gap-8px text-xs text-gray-400">
                <span>{{ formatTime(item.created_at) }}</span>
                <template v-if="item.feedback_no">
                  <span>·</span>
                  <span
                    class="font-mono text-primary hover:underline"
                    @click.stop="copyFeedbackNo(item.feedback_no)"
                  >
                    {{ item.feedback_no }}
                  </span>
                  <span v-if="copied && copiedNo === item.feedback_no" class="text-green-600 dark:text-green-400">
                    {{ t('support.feedbackNoCopied') }}
                  </span>
                </template>
                <span class="ml-auto text-primary">{{ expandedFeedbackNo === item.feedback_no ? t('support.collapseChat') : t('support.expandChat') }}</span>
              </div>
              <p class="text-sm text-gray-600 dark:text-gray-300 leading-relaxed whitespace-pre-line break-words line-clamp-2">{{ item.description }}</p>
            </button>
            <a
              v-if="item.log_file_path"
              :href="item.log_file_path"
              target="_blank"
              rel="noopener noreferrer"
              class="text-xs text-primary hover:underline self-start"
              @click.stop
            >
              📎 {{ item.log_file_name }}
            </a>

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