import { defineStore } from 'pinia'
import { ref } from 'vue'
import { workspacesApi } from '@/api/workspaces'
import type {
  Workspace,
  Worktree,
  FileStatus,
  CredentialMeta,
  CredentialUpsertBody,
  CreateWorkspaceBody,
  UpdateWorkspaceBody,
  CreateWorktreeBody,
  CommitBody,
} from '@/api/types'

const DEFAULT_POLL_INTERVAL_MS = 1500
const DEFAULT_POLL_MAX_MS = 5 * 60 * 1000

export const useWorkspacesStore = defineStore('workspaces', () => {
  const list = ref<Workspace[]>([])
  const current = ref<Workspace | null>(null)
  const worktrees = ref<Worktree[]>([])
  const credential = ref<CredentialMeta | null>(null)
  const loading = ref(false)

  async function fetchByProject(projectSlug: string) {
    loading.value = true
    try {
      list.value = await workspacesApi.list(projectSlug)
    } finally {
      loading.value = false
    }
  }

  async function fetchOne(wsID: string) {
    current.value = await workspacesApi.get(wsID)
  }

  async function create(projectSlug: string, body: CreateWorkspaceBody) {
    const ws = await workspacesApi.create(projectSlug, body)
    list.value.unshift(ws)
    return ws
  }

  async function update(wsID: string, body: UpdateWorkspaceBody) {
    const ws = await workspacesApi.update(wsID, body)
    if (current.value?.id === wsID) current.value = ws
    // 若 wsID 不在 list 中（如深链直入 Detail 页未加载列表），map 静默 no-op；调用方按需 fetchByProject。
    list.value = list.value.map((w) => (w.id === wsID ? ws : w))
    return ws
  }

  async function remove(wsID: string) {
    await workspacesApi.delete(wsID)
    list.value = list.value.filter((w) => w.id !== wsID)
    if (current.value?.id === wsID) current.value = null
  }

  async function sync(wsID: string) {
    const ws = await workspacesApi.sync(wsID)
    if (current.value?.id === wsID) current.value = ws
    // 同 update：list 中无此 wsID 时 map 是 no-op，调用方负责拉列表。
    list.value = list.value.map((w) => (w.id === wsID ? ws : w))
    return ws
  }

  /**
   * 轮询 workspace.sync_status 直到落到 idle/error，用于 Phase 9 创建/Sync 后等克隆完成。
   *
   * 调用方约定：
   *  - 若已知 ws 在 list 中，调用前请确保该项已加载（否则 list.map 静默 no-op，但 current 仍会刷新）。
   *  - 失败抛出 Error，message 含最后一次观测到的 sync_status，便于 UI 区分超时类型。
   *  - 调用方应自行处理并发：同一 wsID 多次并发轮询不会共享请求。
   *
   * @param wsID  目标 workspace 的 UUID。
   * @param intervalMs 轮询间隔，默认 1500ms。
   * @param maxMs 总超时上限，默认 5 分钟（覆盖中等仓库克隆耗时）。
   */
  async function pollUntilSettled(
    wsID: string,
    intervalMs = DEFAULT_POLL_INTERVAL_MS,
    maxMs = DEFAULT_POLL_MAX_MS,
  ): Promise<Workspace> {
    const start = Date.now()
    let lastStatus: Workspace['sync_status'] | 'unknown' = 'unknown'
    while (Date.now() - start < maxMs) {
      const ws = await workspacesApi.get(wsID)
      lastStatus = ws.sync_status
      if (current.value?.id === wsID) current.value = ws
      // 同 update：list 中无此 wsID 时 map 是 no-op，仍刷新 current.value。
      list.value = list.value.map((w) => (w.id === wsID ? ws : w))
      if (ws.sync_status !== 'cloning' && ws.sync_status !== 'syncing') return ws
      await new Promise((r) => setTimeout(r, intervalMs))
    }
    throw new Error(`sync polling timed out for workspace ${wsID} (last status: ${lastStatus})`)
  }

  // ===== credential =====
  async function fetchCredential(wsID: string) {
    credential.value = await workspacesApi.getCredential(wsID)
  }
  async function upsertCredential(wsID: string, body: CredentialUpsertBody) {
    credential.value = await workspacesApi.upsertCredential(wsID, body)
  }

  // ===== worktrees =====
  async function fetchWorktrees(wsID: string) {
    worktrees.value = await workspacesApi.listWorktrees(wsID)
  }
  async function createWorktree(wsID: string, body: CreateWorktreeBody) {
    const wt = await workspacesApi.createWorktree(wsID, body)
    worktrees.value.unshift(wt)
    return wt
  }
  async function deleteWorktree(wtID: string) {
    await workspacesApi.deleteWorktree(wtID)
    worktrees.value = worktrees.value.filter((w) => w.id !== wtID)
  }
  async function acquire(wtID: string) {
    const wt = await workspacesApi.acquire(wtID)
    worktrees.value = worktrees.value.map((w) => (w.id === wtID ? wt : w))
    return wt
  }
  async function release(wtID: string) {
    const wt = await workspacesApi.release(wtID)
    worktrees.value = worktrees.value.map((w) => (w.id === wtID ? wt : w))
    return wt
  }

  // ===== git ops（直透 api，store 仅负责状态变化的端点；status/commit/push 不缓存）=====
  async function statusOnMain(wsID: string): Promise<FileStatus[]> {
    return workspacesApi.statusOnMain(wsID)
  }
  async function statusOnWorktree(wtID: string): Promise<FileStatus[]> {
    return workspacesApi.statusOnWorktree(wtID)
  }
  async function commitOnMain(wsID: string, body: CommitBody) {
    return workspacesApi.commitOnMain(wsID, body)
  }
  async function commitOnWorktree(wtID: string, body: CommitBody) {
    return workspacesApi.commitOnWorktree(wtID, body)
  }
  async function pushOnMain(wsID: string) {
    return workspacesApi.pushOnMain(wsID)
  }
  async function pushOnWorktree(wtID: string) {
    return workspacesApi.pushOnWorktree(wtID)
  }

  return {
    list,
    current,
    worktrees,
    credential,
    loading,
    fetchByProject,
    fetchOne,
    create,
    update,
    remove,
    sync,
    pollUntilSettled,
    fetchCredential,
    upsertCredential,
    fetchWorktrees,
    createWorktree,
    deleteWorktree,
    acquire,
    release,
    statusOnMain,
    statusOnWorktree,
    commitOnMain,
    commitOnWorktree,
    pushOnMain,
    pushOnWorktree,
  }
})
