import { db, id, now, visibleClause } from '../db.js';
import { camelFolder, camelIntuneDeployment, camelRunPlan, camelScript } from './mappers.js';
import { normalizeScriptPayload } from '../forms/schemas.js';

export function listFolders(userId) {
  return db.prepare(`SELECT * FROM folders WHERE ${visibleClause()} ORDER BY name`).all(userId, userId).map(camelFolder);
}

export function createFolder(payload, userId) {
  const folderId = id('fld');
  db.prepare(`
    INSERT INTO folders (id, parent_id, name, visibility, owner_user_id, group_id, created_at, updated_at)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?)
  `).run(
    folderId,
    payload.parentId || null,
    payload.name,
    payload.visibility,
    userId,
    payload.groupId || null,
    now(),
    now()
  );
  return camelFolder(db.prepare('SELECT * FROM folders WHERE id = ?').get(folderId));
}

export function updateFolder(folderId, payload, userId) {
  const existing = db.prepare(`SELECT * FROM folders WHERE id = ? AND ${visibleClause()}`).get(folderId, userId, userId);
  if (!existing) return null;
  db.prepare(`
    UPDATE folders SET parent_id = ?, name = ?, visibility = ?, group_id = ?, updated_at = ? WHERE id = ?
  `).run(
    payload.parentId ?? existing.parent_id,
    payload.name || existing.name,
    payload.visibility || existing.visibility,
    payload.groupId ?? existing.group_id,
    now(),
    folderId
  );
  return camelFolder(db.prepare('SELECT * FROM folders WHERE id = ?').get(folderId));
}

export function deleteFolder(folderId, userId) {
  db.prepare(`DELETE FROM folders WHERE id = ? AND ${visibleClause()}`).run(folderId, userId, userId);
}

export function listScripts(userId) {
  return db.prepare(`
    SELECT s.*, f.name AS folder_name, g.name AS group_name
    FROM scripts s
    LEFT JOIN folders f ON f.id = s.folder_id
    LEFT JOIN groups g ON g.id = s.group_id
    WHERE ${visibleClause('s')}
    ORDER BY s.name
  `).all(userId, userId).map(camelScript);
}

export function createScript(body, userId) {
  const payload = normalizeScriptPayload(body);
  const scriptId = id('scr');
  db.prepare(`
    INSERT INTO scripts (id, folder_id, name, description, content, visibility, owner_user_id, group_id, version, created_at, updated_at)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?)
  `).run(scriptId, payload.folderId, payload.name, payload.description, payload.content, payload.visibility, userId, payload.groupId, now(), now());
  db.prepare('INSERT INTO script_versions (id, script_id, version, content, created_by, created_at) VALUES (?, ?, 1, ?, ?, ?)').run(
    id('ver'),
    scriptId,
    payload.content,
    userId,
    now()
  );
  return camelScript(db.prepare('SELECT * FROM scripts WHERE id = ?').get(scriptId));
}

export function cloneScript(scriptId, body, userId) {
  const existing = getScript(scriptId, userId);
  if (!existing) return null;
  return createScript({
    folderId: existing.folderId,
    name: body.name || cloneName(existing.name),
    description: body.description ?? existing.description ?? '',
    content: existing.content,
    visibility: existing.visibility,
    groupId: existing.groupId
  }, userId);
}

export function getScript(scriptId, userId) {
  const row = db.prepare(`SELECT * FROM scripts WHERE id = ? AND ${visibleClause()}`).get(scriptId, userId, userId);
  return row ? camelScript(row) : null;
}

export function updateScript(scriptId, body, userId) {
  const existing = db.prepare(`SELECT * FROM scripts WHERE id = ? AND ${visibleClause()}`).get(scriptId, userId, userId);
  if (!existing) return null;
  const payload = normalizeScriptPayload({ ...existing, ...body });
  const version = Number(existing.version) + 1;
  db.prepare(`
    UPDATE scripts
    SET folder_id = ?, name = ?, description = ?, content = ?, visibility = ?, group_id = ?, version = ?, updated_at = ?
    WHERE id = ?
  `).run(payload.folderId, payload.name, payload.description, payload.content, payload.visibility, payload.groupId, version, now(), scriptId);
  db.prepare('INSERT INTO script_versions (id, script_id, version, content, created_by, created_at) VALUES (?, ?, ?, ?, ?, ?)').run(
    id('ver'),
    scriptId,
    version,
    payload.content,
    userId,
    now()
  );
  return camelScript(db.prepare('SELECT * FROM scripts WHERE id = ?').get(scriptId));
}

export function deleteScript(scriptId, userId) {
  db.prepare(`DELETE FROM scripts WHERE id = ? AND ${visibleClause()}`).run(scriptId, userId, userId);
}

export function scriptUsage(scriptId, userId) {
  const script = getScript(scriptId, userId);
  if (!script) return null;
  const runplans = db.prepare(`
    SELECT r.*, s.name AS script_name, g.name AS group_name,
      (SELECT COUNT(*) FROM runplan_hosts rh WHERE rh.runplan_id = r.id) AS host_count
    FROM runplans r
    JOIN scripts s ON s.id = r.script_id
    LEFT JOIN groups g ON g.id = r.group_id
    WHERE r.script_id = ? AND ${visibleClause('r')}
    ORDER BY r.updated_at DESC
  `).all(scriptId, userId, userId).map(camelRunPlan);
  const intuneDeployments = db.prepare(`
    SELECT d.*, p.name AS profile_name, s.name AS script_name, g.name AS group_name
    FROM intune_deployments d
    LEFT JOIN psadt_profiles p ON p.id = d.profile_id
    LEFT JOIN scripts s ON s.id = d.script_id
    LEFT JOIN groups g ON g.id = d.group_id
    WHERE d.script_id = ? AND ${visibleClause('d')}
    ORDER BY d.updated_at DESC
  `).all(scriptId, userId, userId).map(camelIntuneDeployment);
  return {
    script,
    runplans,
    intuneDeployments,
    total: runplans.length + intuneDeployments.length
  };
}

export function listScriptVersions(scriptId, userId) {
  const script = db.prepare(`SELECT id FROM scripts WHERE id = ? AND ${visibleClause()}`).get(scriptId, userId, userId);
  if (!script) return null;
  return db.prepare('SELECT * FROM script_versions WHERE script_id = ? ORDER BY version DESC').all(scriptId);
}

function cloneName(name = 'Untitled Script.ps1') {
  const match = String(name).match(/^(.*?)(\.[^.]+)?$/);
  const base = match?.[1] || name;
  const extension = match?.[2] || '';
  return `${base} copy${extension}`;
}
