import { NextResponse } from 'next/server';
import { inArray } from 'drizzle-orm';
import { z } from 'zod';

import { withAuth, withPermission } from '@/lib/api/helpers';
import { parseBody } from '@/lib/api/route-helpers';
import { db } from '@/lib/db';
import { systemSettings } from '@/lib/db/schema/system';
import {
  TEMPLATE_CATALOG,
  TEMPLATE_KEYS,
  settingKeyForSubject,
  type TemplateKey,
} from '@/lib/email/template-catalog';
import { upsertSetting, deleteSetting } from '@/lib/services/settings.service';
import { errorResponse } from '@/lib/errors';

const upsertSchema = z.object({
  key: z.enum(TEMPLATE_KEYS),
  subject: z.string().max(300).nullable(),
});

export const GET = withAuth(
  withPermission('admin', 'manage_settings', async (_req, ctx) => {
    try {
      const subjectKeys = TEMPLATE_KEYS.map(settingKeyForSubject);
      const rows = await db
        .select({
          key: systemSettings.key,
          value: systemSettings.value,
          portId: systemSettings.portId,
        })
        .from(systemSettings)
        .where(inArray(systemSettings.key, subjectKeys));

      const byKey = new Map<string, { port?: string; global?: string }>();
      for (const r of rows) {
        const slot = byKey.get(r.key) ?? {};
        if (r.portId === ctx.portId && typeof r.value === 'string') slot.port = r.value;
        if (r.portId === null && typeof r.value === 'string') slot.global = r.value;
        byKey.set(r.key, slot);
      }

      const data = TEMPLATE_KEYS.map((key) => {
        const meta = TEMPLATE_CATALOG[key];
        const settingKey = settingKeyForSubject(key);
        const overrides = byKey.get(settingKey) ?? {};
        const effective = overrides.port ?? overrides.global ?? meta.defaultSubject;
        return {
          key,
          label: meta.label,
          description: meta.description,
          mergeTokens: meta.mergeTokens,
          defaultSubject: meta.defaultSubject,
          subjectOverride: overrides.port ?? null,
          effectiveSubject: effective,
        };
      });

      return NextResponse.json({ data });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);

export const PUT = withAuth(
  withPermission('admin', 'manage_settings', async (req, ctx) => {
    try {
      const body = await parseBody(req, upsertSchema);
      const settingKey = settingKeyForSubject(body.key as TemplateKey);
      const meta = {
        userId: ctx.userId,
        portId: ctx.portId,
        ipAddress: ctx.ipAddress,
        userAgent: ctx.userAgent,
      };
      if (body.subject === null || body.subject === '') {
        // Clear the override (and only at the per-port level - never touch global).
        await deleteSetting(settingKey, ctx.portId, meta);
      } else {
        await upsertSetting(settingKey, body.subject, ctx.portId, meta);
      }
      return NextResponse.json({ data: { ok: true } });
    } catch (error) {
      return errorResponse(error);
    }
  }),
);
