import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import { useAgent, type ChatMessage } from '../composables/useAgent';
import type { WorkspaceAgentSession } from '../services/fileService';
import { createFileServiceClient } from '../services/fileService';

const STORAGE_KEY = 'vibeeditor-agent-sessions';
const MSG_STORAGE_PREFIX = 'vibeeditor-agent-msgs-';

let sessionCounter = 0;

/** 会话元数据 —— 持久化到 localStorage */
export interface AgentSession {
  id: string;
  name: string;
  nameAutoGenerated: boolean;
  createdAt: number;
}

function isCJK(c: string): boolean {
  const code = c.charCodeAt(0);
  return (code >= 0x4e00 && code <= 0x9fff) || (code >= 0x3400 && code <= 0x4dbf);
}

function generateSessionName(text: string): string {
  const maxUnits = 20;
  let units = 0;
  let i = 0;
  for (i = 0; i < text.length; i++) {
    const char = text[i];
    if (char === '\n') break;
    units += isCJK(char) ? 2 : 1;
    if (units > maxUnits) break;
  }
  const name = text.slice(0, i).trim();
  if (!name) return '';
  return name.length < text.trim().length ? name + '...' : name;
}

function loadSessions(): AgentSession[] {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (raw) {
      const data = JSON.parse(raw);
      if (Array.isArray(data)) return data;
    }
  } catch { /* corrupted data, ignore */ }
  return [];
}

function saveSessions(sessions: AgentSession[]) {
  try {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(sessions));
  } catch { /* storage full or unavailable */ }
}

function saveMessages(sessionId: string, messages: ChatMessage[]) {
  try {
    localStorage.setItem(MSG_STORAGE_PREFIX + sessionId, JSON.stringify(messages));
  } catch { /* storage full */ }
}

function loadMessages(sessionId: string): ChatMessage[] {
  try {
    const raw = localStorage.getItem(MSG_STORAGE_PREFIX + sessionId);
    if (raw) {
      const data = JSON.parse(raw);
      if (Array.isArray(data)) return data;
    }
  } catch { /* corrupted data */ }
  return [];
}

function removeMessages(sessionId: string) {
  try {
    localStorage.removeItem(MSG_STORAGE_PREFIX + sessionId);
  } catch { /* ignore */ }
}

/**
 * 会话管理 store —— 管理多个 Agent 会话的标签页状态。
 * 每个会话对应一个独立的 useAgent() 实例。
 */
export const useSessionStore = defineStore('sessions', () => {
  const sessions = ref<AgentSession[]>([]);

  const agents = new Map<string, ReturnType<typeof useAgent>>();

  const activeSessionId = ref<string | null>(null);
  const boundWorkspaceId = ref<string | null>(null);

  let writeQueue: Promise<void> = Promise.resolve();

  // --- Computed ---
  const activeSession = computed<AgentSession | null>(
    () => sessions.value.find(s => s.id === activeSessionId.value) ?? null
  );

  const activeAgent = computed(() => {
    const id = activeSessionId.value;
    return id ? agents.get(id) ?? null : null;
  });

  // --- Methods ---

  /** 绑定到指定工作区：加载工作区会话，或回退到 localStorage（无工作区时） */
  async function bindWorkspace(workspaceId: string | null, agentSessions?: WorkspaceAgentSession[]) {
    // 保存当前工作区会话（如果已绑定）
    if (boundWorkspaceId.value) {
      await saveCurrentSession();
    }

    // 清空所有当前会话
    for (const id of agents.keys()) {
      removeMessages(id);
    }
    agents.clear();
    sessions.value = [];
    activeSessionId.value = null;
    boundWorkspaceId.value = workspaceId;

    if (!workspaceId) {
      // 无工作区：回退到 localStorage 模式
      const stored = loadSessions();
      if (stored.length > 0) {
        for (const s of stored) {
          const agent = useAgent(s.id);
          agents.set(s.id, agent);
          const msgs = loadMessages(s.id);
          if (msgs.length > 0) agent.restoreMessages(msgs);
          sessions.value.push(s);
        }
        activeSessionId.value = sessions.value[0].id;
      } else {
        // localStorage 也无数据：不创建会话
        // Agent panel 将显示"请先打开文件夹"引导（server 模式）
        // 或保持空状态（Electron/browser 模式）
      }
      return;
    }

    // 有工作区：从传入数据恢复或创建默认会话
    if (agentSessions && agentSessions.length > 0) {
      for (const s of agentSessions) {
        const agent = useAgent(s.id);
        agents.set(s.id, agent);
        if (s.messages && s.messages.length > 0) {
          // 构造完整 ChatMessage 对象再恢复（blocks 会丢失但文本保留）
          const msgs: ChatMessage[] = s.messages.map(m => ({
            id: m.id,
            role: m.role as 'user' | 'assistant' | 'system',
            content: m.content,
            timestamp: m.timestamp,
            blocks: [],
          }));
          agent.restoreMessages(msgs);
        }
        sessions.value.push({
          id: s.id,
          name: s.name,
          nameAutoGenerated: s.nameAutoGenerated,
          createdAt: s.createdAt,
        });
      }
      activeSessionId.value = sessions.value[0].id;
    } else {
      // 无持久化会话：创建默认会话
      createSession();
    }
  }

  /** 创建新会话 —— 插入到数组最左侧 */
  function createSession(): AgentSession {
    const id = `session_${++sessionCounter}`;
    const session: AgentSession = {
      id,
      name: '新会话',
      nameAutoGenerated: false,
      createdAt: Date.now(),
    };
    sessions.value.unshift(session);
    activeSessionId.value = id;
    agents.set(id, useAgent(id));
    saveSessions(sessions.value);

    // 同步到工作区
    saveSessionToWorkspace(id).catch(() => {});
    return session;
  }

  /** 关闭会话 —— 若关闭的是活跃会话则切换到相邻会话 */
  function closeSession(id: string) {
    const idx = sessions.value.findIndex(s => s.id === id);
    if (idx === -1) return;
    sessions.value.splice(idx, 1);
    agents.delete(id);
    removeMessages(id);

    // 从工作区删除
    deleteSessionFromWorkspace(id).catch(() => {});

    if (activeSessionId.value === id) {
      if (sessions.value.length > 0) {
        const nextIdx = Math.min(idx, sessions.value.length - 1);
        activeSessionId.value = sessions.value[nextIdx].id;
      } else {
        activeSessionId.value = null;
      }
    }

    saveSessions(sessions.value);
  }

  /** 切换活跃会话 */
  function setActiveSession(id: string) {
    if (sessions.value.find(s => s.id === id)) {
      activeSessionId.value = id;
    }
  }

  /** 手动更新会话名称 */
  function updateSessionName(id: string, name: string) {
    const session = sessions.value.find(s => s.id === id);
    if (session) {
      session.name = name;
      session.nameAutoGenerated = false;
      saveSessions(sessions.value);
    }
  }

  /** 从首条用户消息自动生成会话名称 —— 仅在尚未自动命名时生效 */
  function autoNameFromFirstMessage(sessionId: string, message: string) {
    const session = sessions.value.find(s => s.id === sessionId);
    if (!session || session.nameAutoGenerated) return;
    const name = generateSessionName(message);
    if (name) {
      session.name = name;
      session.nameAutoGenerated = true;
      saveSessions(sessions.value);
    }
  }

  /** 持久化当前活跃会话的消息历史（localStorage + 服务端） */
  async function saveCurrentSession() {
    const id = activeSessionId.value;
    if (!id) return;
    const agent = agents.get(id);
    if (!agent) return;

    // 始终写 localStorage 作为本地缓存
    saveMessages(id, agent.messages.value);

    // 如果绑定了工作区，通过串行队列同步到服务端（避免并发写覆盖）
    if (boundWorkspaceId.value) {
      const data = buildWorkspaceSessionData(id);
      if (!data) return;
      writeQueue = writeQueue.then(async () => {
        const client = createFileServiceClient();
        await client.saveWorkspaceSession(boundWorkspaceId.value!, data);
      });
      await writeQueue;
    }
  }

  // --- 内部辅助 ---

  function buildWorkspaceSessionData(sessionId: string): WorkspaceAgentSession | null {
    const meta = sessions.value.find(s => s.id === sessionId);
    if (!meta) return null;
    const agent = agents.get(sessionId);
    if (!agent) return null;
    return {
      id: meta.id,
      name: meta.name,
      nameAutoGenerated: meta.nameAutoGenerated,
      createdAt: meta.createdAt,
      lastMessageAt: Date.now(),
      messages: agent.messages.value.map(m => ({
        id: m.id,
        role: m.role,
        content: m.content,
        timestamp: m.timestamp,
      })),
    };
  }

  async function saveSessionToWorkspace(sessionId: string) {
    if (!boundWorkspaceId.value) return;
    const data = buildWorkspaceSessionData(sessionId);
    if (!data) return;
    const client = createFileServiceClient();
    await client.saveWorkspaceSession(boundWorkspaceId.value, data);
  }

  async function deleteSessionFromWorkspace(sessionId: string) {
    if (!boundWorkspaceId.value) return;
    const client = createFileServiceClient();
    await client.deleteWorkspaceSession(boundWorkspaceId.value, sessionId);
  }

  return {
    sessions,
    activeSessionId,
    activeSession,
    activeAgent,
    boundWorkspaceId,
    bindWorkspace,
    createSession,
    closeSession,
    setActiveSession,
    updateSessionName,
    autoNameFromFirstMessage,
    saveCurrentSession,
  };
});
