import { defineStore } from 'pinia';
import { ref } from 'vue';
import type { CreateSessionRequest, SessionResponse, SessionSummary, SessionsListResponse } from '@arboretum/shared';
import { api } from '../lib/api';
import { wsClient, type SessionEvent } from '../lib/ws-client';

export const useSessionsStore = defineStore('sessions', () => {
  const sessions = ref<SessionSummary[]>([]);
  const loading = ref(false);
  const loadError = ref<string | null>(null);
  let unsubscribe: (() => void) | null = null;

  // vivantes d'abord, puis par date de création décroissante (même ordre que le serveur)
  function sorted(list: SessionSummary[]): SessionSummary[] {
    return [...list].sort((a, b) => Number(b.live) - Number(a.live) || b.createdAt.localeCompare(a.createdAt));
  }

  function upsert(session: SessionSummary): void {
    const idx = sessions.value.findIndex((s) => s.id === session.id);
    if (idx >= 0) sessions.value.splice(idx, 1, session);
    else sessions.value.push(session);
    sessions.value = sorted(sessions.value);
  }

  function onEvent(e: SessionEvent): void {
    if (e.type === 'session_update') {
      upsert(e.session);
      return;
    }
    const current = sessions.value.find((s) => s.id === e.sessionId);
    if (!current) return;
    upsert({
      ...current,
      status: 'exited',
      live: false,
      exitCode: e.exitCode,
      endedAt: new Date().toISOString(),
      clients: 0,
    });
  }

  async function fetchSessions(): Promise<void> {
    loading.value = true;
    loadError.value = null;
    try {
      const res = await api.get<SessionsListResponse>('/api/v1/sessions');
      sessions.value = sorted(res.sessions);
    } catch (err) {
      loadError.value = err instanceof Error ? err.message : String(err);
    } finally {
      loading.value = false;
    }
  }

  function startRealtime(): void {
    unsubscribe ??= wsClient.subscribeSessions(onEvent);
  }

  function stopRealtime(): void {
    unsubscribe?.();
    unsubscribe = null;
  }

  async function createSession(cwd: string, command: NonNullable<CreateSessionRequest['command']>): Promise<SessionSummary> {
    const body: CreateSessionRequest = { cwd, command };
    const res = await api.post<SessionResponse>('/api/v1/sessions', body);
    upsert(res.session);
    return res.session;
  }

  async function killSession(id: string): Promise<void> {
    await api.delete<{ ok: true }>(`/api/v1/sessions/${id}`);
  }

  // Reprise d'une session morte (nouveau PTY managé dans son cwd d'origine, côté serveur).
  async function resumeSession(id: string): Promise<SessionSummary> {
    const res = await api.post<SessionResponse>(`/api/v1/sessions/${id}/resume`);
    upsert(res.session);
    return res.session;
  }

  // Fork d'une session (vivante ou morte) — ne corrompt jamais l'originale.
  async function forkSession(id: string): Promise<SessionSummary> {
    const res = await api.post<SessionResponse>(`/api/v1/sessions/${id}/fork`);
    upsert(res.session);
    return res.session;
  }

  return {
    sessions,
    loading,
    loadError,
    fetchSessions,
    startRealtime,
    stopRealtime,
    createSession,
    killSession,
    resumeSession,
    forkSession,
  };
});
