/**
 * GET  /api/chat/threads             — list user's threads
 * GET  /api/chat/threads?projectId=… — list user's threads for one project
 * POST /api/chat/threads             — create a new thread (optionally scoped to a project)
 *
 * Threads can be either:
 *   - workspace-level (project_id NULL)  — created from /projects, etc.
 *   - project-scoped  (project_id set)   — created from a project page so
 *     the AI can pin the right project context in its system prompt.
 *
 * The schema is migrated idempotently the first time the route is hit
 * after deploy (no manual migration needed).
 */
import { NextResponse } from 'next/server';
import { requireWorkspacePrincipal } from '@/lib/auth/workspace-auth';
import { query, queryOne } from '@/lib/db-postgres';

let chatTablesReady = false;
async function ensureChatTables() {
  if (chatTablesReady) return;
  await query(`
    CREATE TABLE IF NOT EXISTS fs_chat_threads (
      id         TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
      user_id    TEXT NOT NULL,
      workspace  TEXT NOT NULL DEFAULT '',
      data       JSONB NOT NULL DEFAULT '{}',
      created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
      updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
    );
    CREATE INDEX IF NOT EXISTS fs_chat_threads_user_ws_idx
      ON fs_chat_threads (user_id, workspace, updated_at DESC);

    CREATE TABLE IF NOT EXISTS fs_chat_messages (
      id         BIGSERIAL PRIMARY KEY,
      thread_id  TEXT NOT NULL REFERENCES fs_chat_threads(id) ON DELETE CASCADE,
      user_id    TEXT NOT NULL,
      data       JSONB NOT NULL DEFAULT '{}',
      created_at TIMESTAMPTZ NOT NULL DEFAULT now()
    );
    CREATE INDEX IF NOT EXISTS fs_chat_messages_thread_idx
      ON fs_chat_messages (thread_id, created_at ASC);
  `, []);

  // Idempotent migration: add project_id + composite index for fast
  // per-project listing. No-op on subsequent boots.
  await query(`
    ALTER TABLE fs_chat_threads ADD COLUMN IF NOT EXISTS project_id TEXT;
    CREATE INDEX IF NOT EXISTS fs_chat_threads_user_proj_idx
      ON fs_chat_threads (user_id, project_id, updated_at DESC);
  `, []);

  chatTablesReady = true;
}

export async function GET(request: Request) {
  await ensureChatTables();
  const principal = await requireWorkspacePrincipal(request);
  if (principal instanceof NextResponse) return principal;

  const userRow = await queryOne<{ data: { email?: string } }>(
    `SELECT data FROM fs_users WHERE id = $1 LIMIT 1`,
    [principal.userId]
  );
  if (!userRow?.data?.email) return NextResponse.json({ error: 'Unauthorized user' }, { status: 401 });
  const sessionEmail = userRow.data.email;

  const { searchParams } = new URL(request.url);
  const workspace = searchParams.get('workspace') || '';
  const projectId = searchParams.get('projectId') || null;

  // When projectId is supplied, narrow to that project. When omitted,
  // return only WORKSPACE-level threads (project_id IS NULL) so the
  // workspace chat UI doesn't get spammed with every project's history.
  // LEFT JOIN against fs_chat_messages so each thread row carries a
  // message count. The Sessions tab on the Plan page renders this so
  // the user can tell at a glance which conversations were substantive
  // ("12 messages") vs. abandoned ("1 message").
  const sql = projectId
    ? `SELECT t.id, t.project_id, t.data, t.created_at, t.updated_at,
              COALESCE(m.cnt, 0)::int AS message_count
         FROM fs_chat_threads t
    LEFT JOIN (
                SELECT thread_id, COUNT(*) AS cnt
                  FROM fs_chat_messages
                 GROUP BY thread_id
              ) m ON m.thread_id = t.id
        WHERE t.user_id = $1 AND t.workspace = $2 AND t.project_id = $3
        ORDER BY t.updated_at DESC LIMIT 50`
    : `SELECT t.id, t.project_id, t.data, t.created_at, t.updated_at,
              COALESCE(m.cnt, 0)::int AS message_count
         FROM fs_chat_threads t
    LEFT JOIN (
                SELECT thread_id, COUNT(*) AS cnt
                  FROM fs_chat_messages
                 GROUP BY thread_id
              ) m ON m.thread_id = t.id
        WHERE t.user_id = $1 AND t.workspace = $2 AND t.project_id IS NULL
        ORDER BY t.updated_at DESC LIMIT 50`;
  const args = projectId
    ? [sessionEmail, workspace, projectId]
    : [sessionEmail, workspace];

  const rows = await query<any>(sql, args);

  return NextResponse.json({
    threads: rows.map((r: any) => ({
      id: r.id,
      projectId: r.project_id ?? null,
      title: r.data?.title || 'New conversation',
      summary: r.data?.summary || null,
      messageCount: r.message_count ?? 0,
      updatedAt: r.updated_at,
      createdAt: r.created_at,
    })),
  });
}

export async function POST(request: Request) {
  await ensureChatTables();
  const principal = await requireWorkspacePrincipal(request);
  if (principal instanceof NextResponse) return principal;

  const userRow = await queryOne<{ data: { email?: string } }>(
    `SELECT data FROM fs_users WHERE id = $1 LIMIT 1`,
    [principal.userId]
  );
  if (!userRow?.data?.email) return NextResponse.json({ error: 'Unauthorized user' }, { status: 401 });
  const sessionEmail = userRow.data.email;

  const { workspace, title, projectId } = await request.json().catch(() => ({}));
  if (!workspace) return NextResponse.json({ error: 'workspace required' }, { status: 400 });

  // Verify the project belongs to the requesting user before tagging
  // a thread to it. Silently drop the projectId if the check fails so
  // a misbehaving client can't tag threads onto someone else's project.
  let safeProjectId: string | null = null;
  if (projectId) {
    const owned = await query<{ id: string }>(
      `SELECT p.id FROM fs_projects p
        JOIN fs_users u ON u.id = p.user_id
        WHERE p.id = $1 AND u.data->>'email' = $2 LIMIT 1`,
        [projectId, sessionEmail],
      );
      if (owned.length > 0) safeProjectId = projectId;
    }

    const rows = await query<any>(
      `INSERT INTO fs_chat_threads (user_id, workspace, project_id, data)
       VALUES ($1, $2, $3, $4)
       RETURNING id, project_id, data, created_at, updated_at`,
      [
        sessionEmail,
      workspace,
      safeProjectId,
      JSON.stringify({ title: title || 'New conversation', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }),
    ],
  );

  const r = rows[0];
  return NextResponse.json({
    thread: {
      id: r.id,
      projectId: r.project_id ?? null,
      title: r.data?.title || 'New conversation',
      createdAt: r.created_at,
      updatedAt: r.updated_at,
    },
  });
}
