import { db } from '../db/client.js';
import type { AuditLogEntryRow, AuthContext, FlockNoteRow } from '../types.js';

type AuditLogInput = {
  workspaceId: number;
  auth?: AuthContext;
  action: string;
  entityType: string;
  entityId?: string | null;
  entityName?: string | null;
  details?: Record<string, unknown>;
};

export const createAuditLogEntry = async ({
  workspaceId,
  auth,
  action,
  entityType,
  entityId = null,
  entityName = null,
  details = {},
}: AuditLogInput) => {
  const result = await db.query<AuditLogEntryRow>(
    `INSERT INTO audit_log_entries (workspace_id, user_id, actor_name, actor_email, action, entity_type, entity_id, entity_name, details)
     VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
     RETURNING id, workspace_id, user_id, actor_name, actor_email, action, entity_type, entity_id, entity_name, details, created_at`,
    [
      workspaceId,
      auth?.user.id ?? null,
      auth?.user.name ?? null,
      auth?.user.email ?? null,
      action,
      entityType,
      entityId,
      entityName,
      JSON.stringify(details),
    ],
  );

  return result.rows[0] ?? null;
};

export const listAuditLogEntries = async (workspaceId: number, limit = 100) => {
  const result = await db.query<AuditLogEntryRow>(
    `SELECT id, workspace_id, user_id, actor_name, actor_email, action, entity_type, entity_id, entity_name, details, created_at
     FROM audit_log_entries
     WHERE workspace_id = $1
     ORDER BY created_at DESC
     LIMIT $2`,
    [workspaceId, limit],
  );

  return result.rows;
};

export const listFlockNotes = async (workspaceId: number) => {
  const result = await db.query<FlockNoteRow>(
    `SELECT flock_notes.id,
            flock_notes.workspace_id,
            flock_notes.bird_id,
            birds.name AS bird_name,
            flock_notes.title,
            flock_notes.body,
            flock_notes.created_by_user_id,
            users.name AS created_by_name,
            flock_notes.created_at,
            flock_notes.updated_at
     FROM flock_notes
     LEFT JOIN birds ON birds.id = flock_notes.bird_id
     LEFT JOIN users ON users.id = flock_notes.created_by_user_id
     WHERE flock_notes.workspace_id = $1
     ORDER BY flock_notes.updated_at DESC`,
    [workspaceId],
  );

  return result.rows;
};

export const createFlockNote = async ({
  workspaceId,
  birdId,
  body,
  createdByUserId,
}: {
  workspaceId: number;
  birdId: string | null;
  body: string;
  createdByUserId: string | null;
}) => {
  const title = body.split(/\s+/).join(' ').slice(0, 160) || 'Note';
  const result = await db.query<FlockNoteRow>(
    `WITH inserted_note AS (
       INSERT INTO flock_notes (workspace_id, bird_id, title, body, created_by_user_id)
       SELECT $1, $2, $3, $4, $5
       WHERE $2::uuid IS NULL
          OR EXISTS (
            SELECT 1
            FROM birds
            WHERE birds.id = $2
              AND birds.workspace_id = $1
          )
       RETURNING id, workspace_id, bird_id, title, body, created_by_user_id, created_at, updated_at
     )
     SELECT inserted_note.id,
            inserted_note.workspace_id,
            inserted_note.bird_id,
            birds.name AS bird_name,
            inserted_note.title,
            inserted_note.body,
            inserted_note.created_by_user_id,
            users.name AS created_by_name,
            inserted_note.created_at,
            inserted_note.updated_at
     FROM inserted_note
     LEFT JOIN birds ON birds.id = inserted_note.bird_id
     LEFT JOIN users ON users.id = inserted_note.created_by_user_id`,
    [workspaceId, birdId, title, body, createdByUserId],
  );

  return result.rows[0] ?? null;
};

export const deleteFlockNote = async (noteId: string, workspaceId: number) => {
  const result = await db.query<{ id: string; title: string }>(
    `DELETE FROM flock_notes
     WHERE id = $1
       AND workspace_id = $2
     RETURNING id, title`,
    [noteId, workspaceId],
  );

  return result.rows[0] ?? null;
};
