<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue'
import ChartView from './components/ChartView.vue'
import ChatPanel from './components/ChatPanel.vue'
import LoginScreen from './components/LoginScreen.vue'
import BottomTray from './components/BottomTray.vue'
import { useChartStore } from './stores/chart'
import { useShapeStore } from './stores/shapes'
import { useIndicatorStore } from './stores/indicators'
import { useIndicatorTypesStore } from './stores/indicatorTypes'
import { useChannelStore } from './stores/channel'
import { useResearchTypesStore } from './stores/researchTypes'
import { useStrategyTypesStore } from './stores/strategyTypes'
import { useStateSync } from './composables/useStateSync'
import { wsManager } from './composables/useWebSocket'
import { authService } from './composables/useAuth'

const isAuthenticated = authService.isAuthenticated
const authError = ref<string>()
const isMobile = ref(false)
let stateSyncCleanup: (() => void) | null = null

// Horizontal split: chat width in pixels (fixed, anchored to right edge)
const CHART_MIN_PX = 300
const CHAT_MIN_PX = 240
const CHAT_DEFAULT_RATIO = 0.38
const chatWidth = ref(0)
const windowWidth = ref(0)
let hDragStartX = 0
let hDragStartWidth = 0

const chartVisible = computed(() => windowWidth.value - chatWidth.value - 4 >= CHART_MIN_PX)

function initChatWidth() {
  windowWidth.value = window.innerWidth
  chatWidth.value = Math.round(window.innerWidth * CHAT_DEFAULT_RATIO)
}

function startHDrag(e: PointerEvent) {
  e.preventDefault()
  ;(e.target as HTMLElement).setPointerCapture(e.pointerId)
  hDragStartX = e.clientX
  hDragStartWidth = chatWidth.value
}

function onHDragMove(e: PointerEvent) {
  if (!e.buttons) return
  // dragging right shrinks chat; dragging left grows chat
  const delta = hDragStartX - e.clientX
  const maxChatWidth = windowWidth.value - CHART_MIN_PX - 4
  chatWidth.value = Math.max(CHAT_MIN_PX, Math.min(Math.max(maxChatWidth, CHAT_MIN_PX), hDragStartWidth + delta))
}

// Clamp chatWidth so chat stays within valid range on resize
function clampChatWidth() {
  windowWidth.value = window.innerWidth
  const maxChatWidth = windowWidth.value - CHART_MIN_PX - 4
  chatWidth.value = Math.max(CHAT_MIN_PX, Math.min(Math.max(maxChatWidth, CHAT_MIN_PX), chatWidth.value))
}

// Check screen width for mobile layout
const checkMobile = () => {
  isMobile.value = window.innerWidth < 768
  if (!isMobile.value) clampChatWidth()
}

const chartStore = useChartStore()

// Watch mobile state and update ChartStore
watch(isMobile, (mobile) => {
  if (mobile) {
    chartStore.symbol = null as any
    chartStore.start_time = null
    chartStore.end_time = null
    chartStore.period = null as any
  }
})

// Check if user is already authenticated on page load
onMounted(async () => {
  initChatWidth()
  checkMobile()
  window.addEventListener('resize', checkMobile)

  const token = authService.getToken()
  if (token) {
    const sessionValid = await authService.checkAuth()
    if (sessionValid) {
      isAuthenticated.value = true
      try {
        await wsManager.connect(token)
        await initializeApp()
      } catch (err) {
        console.error('Failed to connect WebSocket on session restore:', err)
      }
    }
  }
})

const handleAuthenticate = async (email: string, password: string) => {
  authError.value = undefined
  try {
    const result = await authService.login(email, password)
    if (!result.success) {
      authError.value = result.error || 'Login failed'
      return
    }
    if (!result.token) {
      authError.value = 'No token received from server'
      return
    }
    await wsManager.connect(result.token)
    await initializeApp()
  } catch (err: any) {
    authError.value = err.message || 'Authentication failed'
    console.error('Authentication error:', err)
  }
}

const initializeApp = async () => {
  const chartStore = useChartStore()
  const shapeStore = useShapeStore()
  const indicatorStore = useIndicatorStore()
  const indicatorTypesStore = useIndicatorTypesStore()
  const channelStore = useChannelStore()
  const researchTypesStore = useResearchTypesStore()
  const strategyTypesStore = useStrategyTypesStore()
  const stateSync = useStateSync({
    chartState: chartStore,
    shapes: shapeStore,
    indicators: indicatorStore,
    indicator_types: indicatorTypesStore,
    research_types: researchTypesStore,
    strategy_types: strategyTypesStore,
    channelState: channelStore
  })
  stateSyncCleanup = stateSync.cleanup
}

onBeforeUnmount(() => {
  window.removeEventListener('resize', checkMobile)
  if (stateSyncCleanup) stateSyncCleanup()
  wsManager.disconnect()
})
</script>

<template>
  <div class="app-container dark">
    <LoginScreen
      v-if="!isAuthenticated"
      :error-message="authError"
      @authenticate="handleAuthenticate"
    />
    <div v-else-if="!isMobile" class="desktop-layout">
      <div class="top-area">
        <div v-if="chartVisible" class="chart-panel">
          <ChartView />
        </div>
        <div v-if="chartVisible" class="h-grabber" @pointerdown="startHDrag" @pointermove="onHDragMove" />
        <div class="chat-panel" :style="{ width: chatWidth + 'px' }">
          <ChatPanel />
        </div>
      </div>
      <BottomTray />
    </div>
    <div v-else class="mobile-layout">
      <ChatPanel />
    </div>
  </div>
</template>

<style scoped>
.app-container {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: #0f0f0f;
}

.desktop-layout {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

.top-area {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: row;
  overflow: hidden;
}

.chart-panel {
  flex: 1;
  min-width: 0;
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.h-grabber {
  width: 4px;
  flex-shrink: 0;
  height: 100%;
  background: #2e2e2e;
  cursor: col-resize;
}

.h-grabber:hover {
  background: #444;
}

.chat-panel {
  flex-shrink: 0;
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.mobile-layout {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
</style>
