<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useTabStore } from '@/pinia/tab'
import HomeEntryView from '@/features/workbench/components/HomeEntryView.vue'
import Tab from '@/layout/tab.vue'
import { waitForHydration } from '@/pinia/Plugin/indexdb'
import localforage from 'localforage'
import {
  buildProjectUrl,
  DEFAULT_PROJECT_ID,
  ensureProjectIdInUrl,
  FORCE_HOME_QUERY_KEY,
  getProjectDbName,
  NEW_PROJECT_QUERY_KEY,
  PROJECT_TAB_ID,
  QUICK_PROJECT_ID
} from '@/lib/workspace'
import { collectActiveProjectSessionLocks, initProjectSessionLock } from '@/lib/projectSessionLock'
import { listenProjectDeleted, listenResetAll } from '@/lib/projectEvents'
import { createProject, listProjects, type ProjectMeta } from '@/lib/projectRegistry'

const tabStore = useTabStore()
const { t } = useI18n()
const isReady = ref(false)
const lockConflict = ref(false)
const currentProjectId = ref('')
const currentProjectName = ref('')
const conflictProjectList = ref<ProjectMeta[]>([])
const openedProjectIds = ref<string[]>([])
const closeCountdown = ref(10)
let closeCountdownTimer: ReturnType<typeof setInterval> | null = null
let releaseLock: (() => void) | null = null
let stopProjectDeletedListener: (() => void) | null = null
let stopResetAllListener: (() => void) | null = null
let isHandlingDeletedProject = false
let isHandlingGlobalReset = false

const showHomeEntry = computed(() => !tabStore.hasCompletedSetup)

const handleImportComplete = () => {
  tabStore.hasCompletedSetup = true
}

const refreshConflictProjectList = () => {
  void (async () => {
    const projects = listProjects()
    const enriched = await Promise.all(
      projects.map(async (project) => {
        try {
          const kvStoreInstance = localforage.createInstance({
            name: getProjectDbName(project.id),
            storeName: 'pinia-kv'
          })
          const kvState = await kvStoreInstance.getItem<any>('pinia-kv')
          const entries = kvState?.entries && typeof kvState.entries === 'object' ? kvState.entries : null
          const projectInfo = entries?.['xm-base-info-v1']
          const projectName =
            projectInfo && typeof projectInfo === 'object' && typeof projectInfo.projectName === 'string'
              ? projectInfo.projectName.trim()
              : ''
          return {
            ...project,
            name: projectName || project.name
          }
        } catch {
          return project
        }
      })
    )
    conflictProjectList.value = enriched
    const hit = enriched.find(item => item.id === currentProjectId.value)
    currentProjectName.value = hit?.name || currentProjectId.value
    openedProjectIds.value = Array.from(collectActiveProjectSessionLocks(enriched.map(item => item.id)))
  })()
}

const clearCloseCountdown = () => {
  if (!closeCountdownTimer) return
  clearInterval(closeCountdownTimer)
  closeCountdownTimer = null
}

const startCloseCountdown = () => {
  clearCloseCountdown()
  closeCountdown.value = 10
  closeCountdownTimer = setInterval(() => {
    closeCountdown.value -= 1
    if (closeCountdown.value <= 0) {
      clearCloseCountdown()
      try {
        window.close()
      } catch {
        // 部分浏览器会阻止关闭，保留阻断页。
      }
    }
  }, 1000)
}

const isConflictProjectOpen = (projectId: string) => openedProjectIds.value.includes(projectId)

const openProjectInNewTab = (projectId: string, options?: { newProject?: boolean }) => {
  if (isConflictProjectOpen(projectId)) return
  const href = buildProjectUrl(projectId, options)
  window.open(href, '_blank', 'noopener')
}

const createProjectAndOpen = () => {
  const project = createProject()
  refreshConflictProjectList()
  openProjectInNewTab(project.id, { newProject: true })
}

const formatProjectEditedTime = (value: string) => {
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return '-'
  const pad = (num: number) => String(num).padStart(2, '0')
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`
}

const handleReleaseProjectLock = () => {
  if (!releaseLock) return
  releaseLock()
  releaseLock = null
  lockConflict.value = false
}

const handleProjectDeleted = (deletedProjectId: string) => {
  if (String(deletedProjectId || '').trim() !== currentProjectId.value) return
  if (isHandlingDeletedProject) return
  isHandlingDeletedProject = true
  handleReleaseProjectLock()
  tabStore.resetTabs()
  tabStore.hasCompletedSetup = false
  const href = buildProjectUrl(DEFAULT_PROJECT_ID, { forceHome: true })
  try {
    window.close()
  } catch {
    // ignore and fallback to redirect
  }
  window.setTimeout(() => {
    window.location.href = href
  }, 120)
}

const handleResetAll = () => {
  if (isHandlingGlobalReset) return
  isHandlingGlobalReset = true
  handleReleaseProjectLock()
  tabStore.resetTabs()
  tabStore.hasCompletedSetup = false
  const href = buildProjectUrl(DEFAULT_PROJECT_ID, { forceHome: true })
  try {
    window.close()
  } catch {
    // ignore and fallback to redirect
  }
  window.setTimeout(() => {
    window.location.href = href
  }, 120)
}

onMounted(() => {
  currentProjectId.value = ensureProjectIdInUrl()
  refreshConflictProjectList()
  let isNewProjectRequest = false
  let forceHomeRequest = false
  try {
    const url = new URL(window.location.href)
    isNewProjectRequest = url.searchParams.get(NEW_PROJECT_QUERY_KEY) === '1'
    forceHomeRequest = url.searchParams.get(FORCE_HOME_QUERY_KEY) === '1'
  } catch {
    isNewProjectRequest = false
    forceHomeRequest = false
  }
  if (currentProjectId.value !== QUICK_PROJECT_ID) {
    const lock = initProjectSessionLock({
      projectId: currentProjectId.value,
      onConflict: (next) => {
        lockConflict.value = next
        if (next) {
          refreshConflictProjectList()
          startCloseCountdown()
        } else {
          clearCloseCountdown()
        }
      }
    })
    releaseLock = lock.release
  } else {
    lockConflict.value = false
  }

  window.addEventListener('home-import-selected', handleImportComplete)
  window.addEventListener('jgjs-release-project-lock', handleReleaseProjectLock)
  stopProjectDeletedListener = listenProjectDeleted(handleProjectDeleted)
  stopResetAllListener = listenResetAll(handleResetAll)
  waitForHydration('tabs').then(() => {
    if (forceHomeRequest) {
      tabStore.resetTabs()
      tabStore.hasCompletedSetup = false
    }
    if (!tabStore.hasCompletedSetup && !isNewProjectRequest && !forceHomeRequest) {
      const hasProjects = listProjects().length > 0
      if (hasProjects) {
        if (Array.isArray(tabStore.tabs) && tabStore.tabs.length > 0) {
          tabStore.hasCompletedSetup = true
        } else {
          tabStore.enterWorkspace({
            id: PROJECT_TAB_ID,
            title: t('home.cards.projectBudget'),
            componentName: 'ProjectCalcView'
          })
          tabStore.hasCompletedSetup = true
        }
      }
    }
    if (tabStore.hasCompletedSetup && Array.isArray(tabStore.tabs) && tabStore.tabs.length > 0) {
      const activeId = typeof tabStore.activeTabId === 'string' ? tabStore.activeTabId : ''
      const hasActive = Boolean(activeId) && tabStore.tabs.some(tab => tab.id === activeId)
      if (!hasActive) {
        tabStore.activeTabId = tabStore.tabs[0]?.id
      }
    }
    isReady.value = true
  })
})

onBeforeUnmount(() => {
  clearCloseCountdown()
  window.removeEventListener('home-import-selected', handleImportComplete)
  window.removeEventListener('jgjs-release-project-lock', handleReleaseProjectLock)
  if (stopProjectDeletedListener) {
    stopProjectDeletedListener()
    stopProjectDeletedListener = null
  }
  if (stopResetAllListener) {
    stopResetAllListener()
    stopResetAllListener = null
  }
  if (releaseLock) {
    releaseLock()
    releaseLock = null
  }
})
</script>

<template>
  <template v-if="isReady">
    <div
      v-if="lockConflict"
      class="flex min-h-screen items-center justify-center bg-slate-50 px-4"
    >
      <div class="w-full max-w-lg rounded-xl border border-red-200 bg-white p-6 shadow-sm">
        <h2 class="text-lg font-semibold text-slate-900">{{ t('app.projectConflict.title') }}</h2>
        <p class="mt-2 text-sm leading-6 text-slate-600">
          {{ t('app.projectConflict.desc', { name: currentProjectName }) }}
        </p>
        <p class="mt-2 text-xs text-slate-500">
          {{ t('app.projectConflict.countdown', { seconds: closeCountdown }) }}
        </p>
        <div class="mt-4 max-h-52 space-y-2 overflow-auto rounded-md border border-slate-200 bg-slate-50 p-2">
          <button
            v-for="project in conflictProjectList"
            :key="project.id"
            type="button"
            class="flex w-full items-center justify-between rounded-md border border-transparent bg-white px-3 py-2 text-left text-sm transition"
            :class="isConflictProjectOpen(project.id) ? 'cursor-not-allowed opacity-60' : 'cursor-pointer hover:border-slate-200 hover:bg-slate-100'"
            :disabled="isConflictProjectOpen(project.id)"
            @click="openProjectInNewTab(project.id)"
          >
            <span class="font-medium text-slate-700">
              {{ project.name }}
              <span v-if="isConflictProjectOpen(project.id)" class="ml-1 text-xs text-slate-500">{{ t('app.projectConflict.opened') }}</span>
            </span>
            <span class="text-xs text-slate-500">{{ t('app.projectConflict.lastEdited', { time: formatProjectEditedTime(project.updatedAt) }) }}</span>
          </button>
        </div>
        <div class="mt-4 flex items-center gap-2">
          <button
            type="button"
            class="cursor-pointer rounded-md border border-slate-300 bg-white px-3 py-2 text-sm text-slate-700 hover:bg-slate-100"
            @click="createProjectAndOpen"
          >
            {{ t('app.projectConflict.createAndOpen') }}
          </button>
          <button
            type="button"
            class="rounded-md border border-slate-300 bg-white px-3 py-2 text-sm text-slate-700"
            :class="isConflictProjectOpen('default') ? 'cursor-not-allowed opacity-60' : 'cursor-pointer hover:bg-slate-100'"
            :disabled="isConflictProjectOpen('default')"
            @click="openProjectInNewTab('default')"
          >
            {{ t('app.projectConflict.openDefault') }}
          </button>
        </div>
      </div>
    </div>
    <template v-else>
      <HomeEntryView v-if="showHomeEntry" />
      <Tab v-else />
    </template>
  </template>
</template>
