<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import { cn } from '@/lib/utils'
import { useLocalTranslation } from '@/lib/composables/useLocalTranslation'
import ChatWindow from '@/ui/chatbot-popup/chat-window-screen/ChatWindow.vue'
import ChatWindowHeader from '@/ui/chatbot-popup/chat-window-screen/ChatWindowHeader.vue'
import ErrorScreen from '@/ui/chatbot-popup/error-screen/ErrorScreen.vue'
import LoadingScreen from '@/ui/chatbot-popup/loading-screen/LoadingScreen.vue'
import OptionsListScreen from '@/ui/chatbot-popup/options-list-screen/OptionsListScreen.vue'
import ActiveChatActions from '@/ui/chatbot-popup/ActiveChatActions.vue'
import ConfirmationModal from '@/ui/confirmation-modal/ConfirmationModal.vue'
import ReviewDialog from '@/ui/review-dialog/ReviewDialog.vue'
import type { HelpScreenData, Message, Option, ReviewProps } from '@/lib/types'

const POPUP_ANIMATION_DURATION_MS = 250

const props = withDefaults(defineProps<{
  isOpen: boolean
  isClosing?: boolean
  helpScreen: HelpScreenData | null
  status: string
  error: string | null
  messages: Message[]
  assistantStatus: string
  needsAgent: boolean
  sessionId: string | null
  isChatClosed: boolean
  selectedOption: Option | null
  inChatReviewSessionId?: string | null
  isSubmittingReview?: boolean
  navigateToOptionsListAfterReview?: boolean
  isReviewDialogOpen?: boolean
  reviewSessionId?: string | null
  onClose: () => void
  onCloseAnimationEnd?: () => void
  onStartChat: (option: Option) => void
  onSendMessage: (message: string, attachmentIds: string[]) => void
  onEnsureSession: () => Promise<string>
  onEndChat: (options?: { fromChatScreen?: boolean; sessionClosedByServer?: boolean }) => void | Promise<void>
  setSelectedOption: (option: Option | null) => void
  onInChatReviewSubmit?: (payload: ReviewProps) => void | Promise<void>
  onInChatReviewDone?: () => void
  onNavigatedToOptionsList?: () => void
  onReviewDialogSubmit?: (payload: ReviewProps) => void | Promise<void>
  onReviewDialogClose?: () => void
}>(), {
  isClosing: false,
  inChatReviewSessionId: null,
  isSubmittingReview: false,
  navigateToOptionsListAfterReview: false,
  isReviewDialogOpen: false,
  reviewSessionId: null,
})

const { t } = useLocalTranslation()
const showChat = ref(false)
const endChatConfirmation = ref(false)
const startNewChatConfirmation = ref(false)
const tempSelectedOption = ref<Option | null>(null)
const isEntering = ref(true)
const prevIsOpen = ref(false)

onMounted(() => {
  requestAnimationFrame(() => { requestAnimationFrame(() => { isEntering.value = false }) })
})

watch(
  () => props.isClosing,
  (closing) => {
    if (closing && props.onCloseAnimationEnd) {
      setTimeout(props.onCloseAnimationEnd, POPUP_ANIMATION_DURATION_MS)
    }
  }
)

watch(
  () => [props.isOpen, props.sessionId, props.selectedOption] as const,
  ([open, sid, opt]) => {
    const justOpened = open && !prevIsOpen.value
    prevIsOpen.value = open
    if (justOpened && sid && opt && !showChat.value) showChat.value = true
  }
)

watch(
  () => props.navigateToOptionsListAfterReview,
  (navigate) => {
    if (navigate) {
      showChat.value = false
      props.setSelectedOption(null)
      props.onNavigatedToOptionsList?.()
    }
  }
)

function handleBack() {
  if (showChat.value) {
    showChat.value = false
  } else if (props.selectedOption) {
    props.setSelectedOption(null)
  }
}

function handleStartChat(option: Option) {
  if (!option) return
  if (props.sessionId) {
    startNewChatConfirmation.value = true
    tempSelectedOption.value = option
  } else {
    showChat.value = true
    props.onStartChat(option)
    props.setSelectedOption(option)
  }
}

function handleSendMessage(message: string, attachmentIds: string[]) {
  if (message.trim() || attachmentIds.length > 0) {
    props.onSendMessage(message.trim(), attachmentIds)
  }
}

async function handleEndAndStartNewChat() {
  if (!tempSelectedOption.value) return
  startNewChatConfirmation.value = false
  await props.onEndChat()
  showChat.value = true
  props.onStartChat(tempSelectedOption.value)
  props.setSelectedOption(tempSelectedOption.value)
  tempSelectedOption.value = null
}

async function handleEndChatFromChatScreen() {
  endChatConfirmation.value = false
  if (!props.sessionId) { showChat.value = false; props.setSelectedOption(null); return }
  await props.onEndChat({ fromChatScreen: true })
}

async function handleEndChatFromActiveActions() {
  await props.onEndChat()
  showChat.value = false
  props.setSelectedOption(null)
}

const popupBaseClasses = 'babylai:fixed babylai:inset-auto babylai:max-w-sm babylai:h-[calc(100vh-220px)] babylai:max-h-[800px] babylai:overflow-auto babylai:w-full babylai:bg-secondary babylai:mb-4 babylai:bottom-24 babylai:right-4 babylai:rounded-3xl babylai:shadow-lg babylai:z-50 babylai:flex babylai:flex-col'
const popupAnimationClasses = computed(() =>
  cn(
    'babylai:transition-all babylai:duration-[250ms] babylai:ease-out',
    (isEntering.value || props.isClosing) && 'babylai:opacity-0 babylai:scale-[0.96] babylai:translate-y-2',
    !isEntering.value && !props.isClosing && 'babylai:opacity-100 babylai:scale-100 babylai:translate-y-0'
  )
)
</script>

<template>
  <!-- Loading state -->
  <div v-if="status === 'loading' && !helpScreen" :class="cn(popupBaseClasses, popupAnimationClasses)">
    <LoadingScreen @close="onClose" />
  </div>

  <!-- Error state -->
  <div v-else-if="error" :class="cn(popupBaseClasses, popupAnimationClasses)">
    <ErrorScreen :error="error || ''" @close="onClose" />
  </div>

  <!-- Main popup -->
  <div v-else :class="cn(popupBaseClasses, popupAnimationClasses)">
    <div class="babylai:h-full babylai:rounded-3xl babylai:flex babylai:flex-col babylai:relative">

      <!-- Active chat overlay when session exists but chat hidden -->
      <ActiveChatActions
        v-if="sessionId && !showChat"
        @confirm="handleEndChatFromActiveActions"
        @cancel="showChat = true"
      />

      <!-- Chat view -->
      <template v-if="showChat && selectedOption">
        <ChatWindowHeader
          :option-title="selectedOption.title"
          :handle-back="handleBack"
          :handle-end-chat="() => endChatConfirmation = true"
          :handle-minimize="onClose"
        />
        <ChatWindow
          :on-send-message="handleSendMessage"
          :on-ensure-session="onEnsureSession"
          :messages="messages"
          :assistant-status="assistantStatus"
          :needs-agent="needsAgent"
          :session-id="sessionId"
          :is-chat-closed="isChatClosed"
          :in-chat-review-session-id="inChatReviewSessionId"
          :is-submitting-review="isSubmittingReview"
          :on-in-chat-review-submit="onInChatReviewSubmit"
          :on-in-chat-review-done="onInChatReviewDone"
        />
      </template>

      <!-- Options list view -->
      <OptionsListScreen
        v-else
        :help-screen="helpScreen"
        :has-active-session="!!sessionId"
        @start-chat="handleStartChat"
        @minimize="onClose"
      />

      <!-- End chat confirmation -->
      <ConfirmationModal
        v-if="endChatConfirmation"
        :title="t('homeSdk.ConfirmationModal.title')"
        :message="t('homeSdk.ConfirmationModal.message')"
        :on-cancel="() => endChatConfirmation = false"
        :on-confirm="handleEndChatFromChatScreen"
      />

      <!-- Start new chat confirmation -->
      <ConfirmationModal
        v-if="startNewChatConfirmation"
        :title="t('homeSdk.ConfirmationModal.endAndStartNewChatTitle')"
        :message="t('homeSdk.ConfirmationModal.endAndStartNewChatMessage')"
        :on-cancel="() => startNewChatConfirmation = false"
        :on-confirm="handleEndAndStartNewChat"
      />

      <!-- Review dialog -->
      <ReviewDialog
        v-if="isReviewDialogOpen && reviewSessionId && onReviewDialogSubmit && onReviewDialogClose"
        :is-submitting="isSubmittingReview"
        @submit="onReviewDialogSubmit"
        @close="onReviewDialogClose"
      />
    </div>
  </div>
</template>
