import type { Cookies } from '@sveltejs/kit';
import { dev } from '$app/environment';
import * as fs from 'node:fs';
import * as path from 'node:path';

const SESSION_COOKIE = 'plebsaber_session';
const DATA_DIR = '.data';
const SESSION_FILE = 'plebsaber_sessions.json';

export type StoredSession = {
  sessionId: string;
  beatleaderId: string;
  name: string | null;
  avatar: string | null;
  createdAt: number;
  lastSeenAt: number;
};

function ensureDataDir(): void {
  if (!fs.existsSync(DATA_DIR)) {
    fs.mkdirSync(DATA_DIR, { recursive: true });
  }
}

function sessionFilePath(): string {
  return path.join(process.cwd(), DATA_DIR, SESSION_FILE);
}

function readSessions(): Record<string, StoredSession> {
  try {
    const file = sessionFilePath();
    if (!fs.existsSync(file)) return {};
    const raw = fs.readFileSync(file, 'utf-8');
    const parsed = JSON.parse(raw);
    if (parsed && typeof parsed === 'object') {
      return parsed as Record<string, StoredSession>;
    }
  } catch (err) {
    console.error('Failed to read session store', err);
  }
  return {};
}

function writeSessions(sessions: Record<string, StoredSession>): void {
  try {
    ensureDataDir();
    fs.writeFileSync(sessionFilePath(), JSON.stringify(sessions, null, 2), 'utf-8');
  } catch (err) {
    console.error('Failed to persist session store', err);
  }
}

export function getAllSessions(): StoredSession[] {
  const sessions = readSessions();
  return Object.values(sessions);
}

function baseCookieOptions() {
  return {
    path: '/',
    httpOnly: true as const,
    sameSite: 'lax' as const,
    secure: !dev
  };
}

export function upsertSession(
  cookies: Cookies,
  input: { beatleaderId: string; name: string | null; avatar: string | null }
): StoredSession {
  const sessions = readSessions();
  const existingSessionId = cookies.get(SESSION_COOKIE);
  const now = Date.now();

  if (existingSessionId && sessions[existingSessionId]?.beatleaderId === input.beatleaderId) {
    const current = sessions[existingSessionId];
    const updated: StoredSession = {
      ...current,
      name: input.name,
      avatar: input.avatar,
      lastSeenAt: now
    };
    sessions[existingSessionId] = updated;
    writeSessions(sessions);
    cookies.set(SESSION_COOKIE, existingSessionId, { ...baseCookieOptions(), maxAge: 10 * 365 * 24 * 3600 });
    return updated;
  }

  const sessionId = crypto.randomUUID();
  const session: StoredSession = {
    sessionId,
    beatleaderId: input.beatleaderId,
    name: input.name,
    avatar: input.avatar,
    createdAt: now,
    lastSeenAt: now
  };

  sessions[sessionId] = session;
  writeSessions(sessions);

  cookies.set(SESSION_COOKIE, sessionId, { ...baseCookieOptions(), maxAge: 10 * 365 * 24 * 3600 });
  return session;
}

export function getSession(cookies: Cookies): StoredSession | null {
  const sessionId = cookies.get(SESSION_COOKIE);
  if (!sessionId) return null;
  const sessions = readSessions();
  const session = sessions[sessionId];
  if (!session) return null;

  session.lastSeenAt = Date.now();
  sessions[sessionId] = session;
  writeSessions(sessions);
  return session;
}

export function clearSession(cookies: Cookies): void {
  const sessionId = cookies.get(SESSION_COOKIE);
  if (!sessionId) return;

  const sessions = readSessions();
  if (sessions[sessionId]) {
    delete sessions[sessionId];
    writeSessions(sessions);
  }

  cookies.delete(SESSION_COOKIE, baseCookieOptions());
}
