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

const props = defineProps<{
  item: SupportFeedbackItem;
  verifiedEmail: string | null;
}>();

const emit = defineEmits<{
  verified: [email: string];
  statusUpdate: [status: string];
}>();

const { t } = useI18n();
const { getFeedbackMessages, sendFeedbackMessage } = useSiteApi();

const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const POLL_INTERVAL_MS = 4000;

const emailInput = ref('');
const emailError = ref('');
const messages = ref<SupportFeedbackMessage[]>([]);
const replyContent = ref('');
const loading = ref(false);
const sending = ref(false);
const sendError = ref('');
const messageListRef = ref<HTMLElement | null>(null);
let pollTimer: ReturnType<typeof setInterval> | null = null;

const effectiveEmail = computed(() => props.verifiedEmail || '');
const isResolved = computed(() => props.item.status === 'resolved');

function lastMessageId(): number {
  return messages.value.length > 0 ? messages.value[messages.value.length - 1].id : 0;
}

async function scrollToBottom() {
  await nextTick();
  const el = messageListRef.value;
  if (el) el.scrollTop = el.scrollHeight;
}

async function loadMessages(full = false) {
  if (!effectiveEmail.value) return;
  if (full) loading.value = true;
  try {
    const sinceId = full ? undefined : lastMessageId();
    const data = await getFeedbackMessages(props.item.feedback_no, effectiveEmail.value, sinceId);
    if (data?.status && data.status !== props.item.status) {
      emit('statusUpdate', data.status);
    }
    const incoming = data?.items || [];
    if (full || sinceId === 0) {
      messages.value = incoming;
    } else if (incoming.length > 0) {
      messages.value = [...messages.value, ...incoming];
    }
    if (full || incoming.length > 0) await scrollToBottom();
  } catch (e) {
    if (full) throw e;
  } finally {
    if (full) loading.value = false;
  }
}

function startPolling() {
  stopPolling();
  if (isResolved.value) return;
  pollTimer = setInterval(() => {
    if (effectiveEmail.value && document.visibilityState === 'visible' && !isResolved.value) {
      loadMessages(false);
    }
  }, POLL_INTERVAL_MS);
}

function stopPolling() {
  if (pollTimer) {
    clearInterval(pollTimer);
    pollTimer = null;
  }
}

function handleVerifyEmail() {
  const email = emailInput.value.trim();
  if (!EMAIL_RE.test(email)) {
    emailError.value = t('form.invalidEmail');
    return;
  }
  emailError.value = '';
  emit('verified', email);
}

async function handleSend() {
  const content = replyContent.value.trim();
  if (!content || !effectiveEmail.value || sending.value || isResolved.value) return;
  sending.value = true;
  sendError.value = '';
  try {
    const data = await sendFeedbackMessage(props.item.feedback_no, effectiveEmail.value, content);
    messages.value = data?.items || [];
    replyContent.value = '';
    await scrollToBottom();
  } catch (e) {
    sendError.value = e instanceof ApiError ? e.message : t('support.messageFailed');
  } finally {
    sending.value = false;
  }
}

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())}`;
}

watch(() => props.verifiedEmail, async (email, prev) => {
  if (email && email !== prev) {
    try {
      await loadMessages(true);
      startPolling();
    } catch (e) {
      emailError.value = e instanceof ApiError ? e.message : t('support.emailMismatch');
      emit('verified', '');
    }
  } else if (!email) {
    stopPolling();
    messages.value = [];
  }
}, { immediate: true });

watch(isResolved, (resolved) => {
  if (resolved) {
    stopPolling();
    replyContent.value = '';
  } else if (effectiveEmail.value) {
    startPolling();
  }
});

onUnmounted(stopPolling);
</script>

<template>
  <div class="mt-4px pt-16px border-t border-gray-100 dark:border-dark-600 flex flex-col gap-12px">
    <div v-if="!effectiveEmail" class="flex flex-col gap-8px">
      <p class="text-xs text-gray-500 dark:text-gray-400">{{ t('support.verifyEmailHint') }}</p>
      <div class="flex gap-8px">
        <input
          v-model="emailInput"
          type="email"
          :placeholder="t('support.emailPlaceholder')"
          class="flex-1 min-w-0 px-12px py-10px rounded-8px border text-sm bg-white dark:bg-dark-800 dark:text-gray-100 outline-none transition-colors"
          :class="emailError ? 'border-red-400' : 'border-gray-200 dark:border-dark-600 focus:border-primary'"
          @keyup.enter="handleVerifyEmail"
        >
        <button
          type="button"
          class="px-16px py-10px rounded-8px bg-primary text-white text-sm font-medium hover:opacity-90 transition-opacity shrink-0"
          @click="handleVerifyEmail"
        >
          {{ t('support.verifyEmail') }}
        </button>
      </div>
      <p v-if="emailError" class="text-xs text-red-500">{{ emailError }}</p>
    </div>

    <template v-else>
      <div class="text-xs text-gray-500 dark:text-gray-400">{{ t('support.initialDescription') }}</div>
      <div
        ref="messageListRef"
        class="max-h-280px overflow-y-auto flex flex-col gap-10px p-12px rounded-8px bg-gray-50/80 dark:bg-dark-700/50 border border-gray-100 dark:border-dark-600"
      >
        <div class="flex justify-end">
          <div class="max-w-[85%] rounded-10px px-12px py-8px text-sm bg-primary text-white">
            <div class="whitespace-pre-wrap break-words">{{ item.description }}</div>
            <div class="text-xs mt-4px opacity-70">{{ formatTime(item.created_at) }}</div>
          </div>
        </div>

        <div v-if="loading && messages.length === 0" class="py-16px text-center text-xs text-gray-400">
          {{ t('common.loading') }}
        </div>
        <div v-else-if="messages.length === 0" class="py-8px text-center text-xs text-gray-400">
          {{ t('support.noMessages') }}
        </div>

        <div
          v-for="msg in messages"
          :key="msg.id"
          class="flex"
          :class="msg.sender_type === 'user' ? 'justify-end' : 'justify-start'"
        >
          <div
            class="max-w-[85%] rounded-10px px-12px py-8px text-sm leading-relaxed"
            :class="msg.sender_type === 'user'
              ? 'bg-primary text-white'
              : 'bg-white dark:bg-dark-800 border border-gray-100 dark:border-dark-600 text-gray-700 dark:text-gray-200'"
          >
            <div v-if="msg.sender_type === 'staff' && msg.sender_name" class="text-xs opacity-80 mb-2px">
              {{ msg.sender_name }}
            </div>
            <div class="whitespace-pre-wrap break-words">{{ msg.content }}</div>
            <div class="text-xs mt-4px opacity-70">{{ formatTime(msg.created_at) }}</div>
          </div>
        </div>
      </div>

      <div v-if="isResolved" class="rounded-8px px-12px py-10px text-xs text-gray-500 dark:text-gray-400 bg-gray-50 dark:bg-dark-700/50 border border-gray-100 dark:border-dark-600">
        {{ t('support.conversationClosed') }}
      </div>
      <div v-else class="flex flex-col gap-8px">
        <textarea
          v-model="replyContent"
          rows="3"
          maxlength="2000"
          :placeholder="t('support.messagePlaceholder')"
          class="px-12px py-10px rounded-8px border border-gray-200 dark:border-dark-600 text-sm bg-white dark:bg-dark-800 dark:text-gray-100 outline-none transition-colors resize-y focus:border-primary"
          @keydown.ctrl.enter.prevent="handleSend"
        />
        <button
          type="button"
          :disabled="sending || !replyContent.trim()"
          class="self-end px-20px py-10px rounded-8px bg-primary text-white text-sm font-medium hover:opacity-90 transition-opacity disabled:opacity-50"
          @click="handleSend"
        >
          {{ sending ? t('common.loading') : t('support.sendMessage') }}
        </button>
        <p v-if="sendError" class="text-xs text-red-500">{{ sendError }}</p>
      </div>
    </template>
  </div>
</template>
