import { NextResponse } from 'next/server';
import { listPlugins, getPlugin, installPlugin, uninstallPlugin, updatePluginConfig, listInstalledPlugins, getInstalledPlugin, getSecretFieldNames } from '@/lib/plugins/registry';
import { executePluginAction } from '@/lib/plugins/executor';

const SECRET_MASK = '••••••••';

function maskInstalledConfig<T extends { definition?: any; config?: Record<string, any> } | null | undefined>(inst: T): T {
  if (!inst || !inst.config) return inst;
  const secrets = getSecretFieldNames(inst.definition || null);
  if (!secrets.length) return inst;
  const masked = { ...inst.config };
  for (const k of secrets) {
    if (typeof masked[k] === 'string' && masked[k]) masked[k] = SECRET_MASK;
  }
  return { ...inst, config: masked } as T;
}

function restoreInstalledConfig(id: string, incoming: Record<string, any>): Record<string, any> {
  const existing = getInstalledPlugin(id);
  if (!existing) return incoming;
  const secrets = getSecretFieldNames(existing.definition);
  if (!secrets.length) return incoming;
  const out = { ...incoming };
  for (const k of secrets) {
    if (out[k] === SECRET_MASK) {
      const prev = existing.config?.[k];
      if (typeof prev === 'string') out[k] = prev;
      else delete out[k];
    }
  }
  return out;
}

// GET: list plugins or get plugin details
export async function GET(req: Request) {
  const url = new URL(req.url);
  const id = url.searchParams.get('id');
  const installed = url.searchParams.get('installed');

  if (id) {
    // Try as plugin definition first, then as installed instance
    const plugin = getPlugin(id);
    const inst = getInstalledPlugin(id);
    if (!plugin && !inst) return NextResponse.json({ error: 'Plugin not found' }, { status: 404 });
    const masked = maskInstalledConfig(inst);
    return NextResponse.json({
      plugin: masked?.definition || plugin,
      installed: !!inst,
      config: masked?.config,
      instanceName: masked?.instanceName,
      source: masked?.source,
    });
  }

  if (installed === 'true') {
    return NextResponse.json({ plugins: listInstalledPlugins().map(p => maskInstalledConfig(p)) });
  }

  return NextResponse.json({ plugins: listPlugins() });
}

// POST: install, uninstall, update config, or test a plugin action
export async function POST(req: Request) {
  const body = await req.json();
  const { action, id, config, actionName, params } = body;

  switch (action) {
    case 'install': {
      if (!id) return NextResponse.json({ error: 'id required' }, { status: 400 });
      const merged = restoreInstalledConfig(id, config || {});
      const ok = installPlugin(id, merged, body.source ? { source: body.source, name: body.name } : undefined);
      return NextResponse.json({ ok });
    }
    case 'create_instance': {
      const { source, name, instanceId } = body;
      if (!source || !name) return NextResponse.json({ error: 'source and name required' }, { status: 400 });
      const iid = instanceId || name.toLowerCase().replace(/[^a-z0-9]+/g, '-');
      // Check for duplicate ID
      const existing = getInstalledPlugin(iid);
      if (existing) {
        return NextResponse.json({ error: `Instance ID "${iid}" already exists (used by ${existing.instanceName || existing.definition.name}). Choose a different name.` }, { status: 409 });
      }
      const ok = installPlugin(iid, config || {}, { source, name });
      return NextResponse.json({ ok, instanceId: iid });
    }
    case 'uninstall': {
      if (!id) return NextResponse.json({ error: 'id required' }, { status: 400 });
      const ok = uninstallPlugin(id);
      return NextResponse.json({ ok });
    }
    case 'update_config': {
      if (!id || !config) return NextResponse.json({ error: 'id and config required' }, { status: 400 });
      const merged = restoreInstalledConfig(id, config);
      const ok = updatePluginConfig(id, merged);
      return NextResponse.json({ ok });
    }
    case 'test': {
      if (!id || !actionName) return NextResponse.json({ error: 'id and actionName required' }, { status: 400 });
      const inst = getInstalledPlugin(id);
      if (!inst) return NextResponse.json({ error: 'Plugin not installed' }, { status: 400 });
      const result = await executePluginAction(inst, actionName, params || {});
      return NextResponse.json(result);
    }
    default:
      return NextResponse.json({ error: 'Unknown action' }, { status: 400 });
  }
}
