<script setup lang="ts">
import { ref, watch, nextTick, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { api, ApiError, type ChatMessage } from '../api'
import Badge from '../components/Badge.vue'

const props = defineProps<{ projectId: string }>()
const router = useRouter()
const { t, locale } = useI18n()

const messages = ref<ChatMessage[]>([])
const input = ref('')
const sending = ref(false)
const loading = ref(true)
const error = ref('')
const consecutiveErrors = ref(0)
const projectName = ref('')
const messagesEl = ref<HTMLElement | null>(null)

let pollTimer: ReturnType<typeof setInterval> | null = null

function stopPoll() {
  if (pollTimer) {
    clearInterval(pollTimer)
    pollTimer = null
  }
}

function hasRunningTasks(msgs: ChatMessage[]) {
  return msgs.some(
    m => m.task_stub?.status === 'in_progress' || m.task_stub?.status === 'pending'
  )
}

function checkAndPoll() {
  stopPoll()
  if (!hasRunningTasks(messages.value)) return
  pollTimer = setInterval(async () => {
    try {
      const updated = await api.chatHistory(props.projectId)
      messages.value = updated
      consecutiveErrors.value = 0
      error.value = ''
      if (!hasRunningTasks(updated)) stopPoll()
    } catch (e: any) {
      consecutiveErrors.value++
      console.warn(`[polling] ошибка #${consecutiveErrors.value}:`, e)
      if (consecutiveErrors.value >= 3) {
        error.value = t('chat.server_unavailable')
        stopPoll()
      }
    }
  }, 3000)
}

async function load() {
  stopPoll()
  loading.value = true
  error.value = ''
  consecutiveErrors.value = 0
  try {
    const [msgs, project] = await Promise.all([
      api.chatHistory(props.projectId),
      api.project(props.projectId),
    ])
    messages.value = msgs
    projectName.value = project.name
  } catch (e: any) {
    if (e instanceof ApiError && e.message.includes('not found')) {
      router.push('/')
      return
    }
    error.value = e.message
  } finally {
    loading.value = false
  }
  await nextTick()
  scrollToBottom()
  checkAndPoll()
}

watch(() => props.projectId, () => {
  messages.value = []
  input.value = ''
  error.value = ''
  projectName.value = ''
  loading.value = true
  load()
}, { immediate: true })

onUnmounted(stopPoll)

async function send() {
  const text = input.value.trim()
  if (!text || sending.value) return
  sending.value = true
  error.value = ''
  try {
    const result = await api.sendChatMessage(props.projectId, text)
    input.value = ''
    messages.value.push(result.user_message, result.assistant_message)
    await nextTick()
    scrollToBottom()
    checkAndPoll()
  } catch (e: any) {
    error.value = e.message
  } finally {
    sending.value = false
  }
}

function onKeydown(e: KeyboardEvent) {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault()
    send()
  }
}

function scrollToBottom() {
  if (messagesEl.value) {
    messagesEl.value.scrollTop = messagesEl.value.scrollHeight
  }
}

function taskStatusColor(status: string): string {
  const map: Record<string, string> = {
    done: 'green',
    in_progress: 'blue',
    review: 'yellow',
    blocked: 'red',
    pending: 'gray',
    cancelled: 'gray',
  }
  return map[status] ?? 'gray'
}

function formatTime(dt: string) {
  return new Date(dt).toLocaleTimeString(locale.value === 'ru' ? 'ru-RU' : 'en-US', { hour: '2-digit', minute: '2-digit' })
}
</script>

<template>
  <div class="flex flex-col h-[calc(100vh-112px)]">
    <!-- Header -->
    <div class="flex items-center gap-3 pb-4 border-b border-gray-800">
      <router-link
        :to="`/project/${projectId}`"
        class="text-gray-400 hover:text-gray-200 text-sm no-underline"
      >{{ t('chat.back_to_project') }}</router-link>
      <span class="text-gray-600">|</span>
      <h1 class="text-base font-semibold text-gray-100">
        {{ projectName || projectId }}
      </h1>
      <span class="text-xs text-gray-500 ml-1">{{ t('chat.chat_label') }}</span>
    </div>

    <!-- Error -->
    <div v-if="error" class="mt-3 text-sm text-red-400 bg-red-900/20 border border-red-800 rounded px-3 py-2">
      {{ error }}
    </div>

    <!-- Loading -->
    <div v-if="loading" class="flex-1 flex items-center justify-center">
      <span class="text-gray-500 text-sm">{{ t('chat.loading') }}</span>
    </div>

    <!-- Messages -->
    <div
      v-else
      ref="messagesEl"
      class="flex-1 overflow-y-auto py-4 flex flex-col gap-3 min-h-0"
    >
      <div v-if="messages.length === 0" class="text-center text-gray-500 text-sm mt-8">
        {{ t('chat.empty_hint') }}
      </div>

      <div
        v-for="msg in messages"
        :key="msg.id"
        class="flex"
        :class="msg.role === 'user' ? 'justify-end' : 'justify-start'"
      >
        <div
          class="max-w-[70%] rounded-2xl px-4 py-2.5"
          :class="msg.role === 'user'
            ? 'bg-indigo-900/60 border border-indigo-700/50 text-gray-100 rounded-br-sm'
            : 'bg-gray-800/70 border border-gray-700/50 text-gray-200 rounded-bl-sm'"
        >
          <p class="text-sm whitespace-pre-wrap break-words">{{ msg.content }}</p>

          <!-- Task stub for task_created messages -->
          <div
            v-if="msg.message_type === 'task_created' && msg.task_stub"
            class="mt-2 pt-2 border-t border-gray-700/40 flex items-center gap-2"
          >
            <router-link
              :to="`/task/${msg.task_stub.id}`"
              class="text-xs text-indigo-400 hover:text-indigo-300 no-underline font-mono"
            >{{ msg.task_stub.id }}</router-link>
            <Badge :color="taskStatusColor(msg.task_stub.status)" :text="msg.task_stub.status" />
          </div>

          <p class="text-xs mt-1.5 text-gray-500">{{ formatTime(msg.created_at) }}</p>
        </div>
      </div>
    </div>

    <!-- Input -->
    <div class="pt-3 border-t border-gray-800 flex gap-2 items-end">
      <textarea
        v-model="input"
        :disabled="sending || loading"
        :placeholder="t('chat.input_placeholder')"
        rows="2"
        class="flex-1 bg-gray-800/60 border border-gray-700 rounded-xl px-4 py-2.5 text-sm text-gray-100 placeholder-gray-500 resize-none focus:outline-none focus:border-indigo-600 disabled:opacity-50"
        @keydown="onKeydown"
      />
      <button
        :disabled="sending || loading || !input.trim()"
        class="px-4 py-2.5 bg-indigo-600 hover:bg-indigo-500 disabled:opacity-40 disabled:cursor-not-allowed text-white text-sm rounded-xl font-medium transition-colors"
        @click="send"
      >
        {{ sending ? t('chat.sending') : t('chat.send') }}
      </button>
    </div>
  </div>
</template>
