import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireRole } from "@/lib/auth";
import { resolveVerificationSetting, toMailView, toSmsView, toWhatsappView } from "@/lib/notify";

/** Institution Control Panel → Email/SMS/WhatsApp (delivery) credentials +
    document-verification module toggles (which prints carry QR codes). */

export async function GET() {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session?.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  const institutionId = session.institutionId;
  const [mail, sms, whatsapp, verification] = await Promise.all([
    prisma.mailSetting.findFirst({ where: { institutionId }, orderBy: { id: "asc" } }),
    prisma.smsSetting.findFirst({ where: { institutionId }, orderBy: { id: "asc" } }),
    prisma.whatsappSetting.findFirst({ where: { institutionId }, orderBy: { id: "asc" } }),
    resolveVerificationSetting(institutionId),
  ]);
  const stats = await prisma.verificationCode.aggregate({
    where: { institutionId },
    _count: { id: true },
    _sum: { scans: true },
  });
  return NextResponse.json({
    mail: toMailView(mail),
    sms: toSmsView(sms),
    whatsapp: toWhatsappView(whatsapp),
    // what the forgot-password flow would actually use right now
    effective: {
      mail: mail?.active ? "INSTITUTION" : (await prisma.mailSetting.findFirst({ where: { scope: "CENTRAL", active: true } })) ? "CENTRAL" : null,
      sms: sms?.active ? "INSTITUTION" : (await prisma.smsSetting.findFirst({ where: { scope: "CENTRAL", active: true } })) ? "CENTRAL" : null,
    },
    verification: {
      ...verification.toggles,
      source: verification.source,
      stats: { codes: stats._count.id, scans: stats._sum.scans ?? 0 },
    },
  });
}

export async function PUT(req: Request) {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session?.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  const institutionId = session.institutionId;
  const body = (await req.json().catch(() => ({}))) as {
    mail?: Record<string, unknown>;
    sms?: Record<string, unknown>;
    whatsapp?: Record<string, unknown>;
    verification?: { result?: boolean; examSchedule?: boolean; inventory?: boolean };
  };

  if (body.verification) {
    const v = body.verification;
    const data = {
      result: v.result !== false,
      examSchedule: v.examSchedule !== false,
      inventory: v.inventory !== false,
      active: true,
    };
    await prisma.verificationSetting.upsert({
      where: { institutionId },
      create: { scope: "INSTITUTION", institutionId, ...data },
      update: data,
    });
  }

  const str = (v: unknown, fallback = "") => (typeof v === "string" ? v.trim() : fallback);
  const num = (v: unknown, fallback: number) => {
    const n = Number(v);
    return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;
  };

  if (body.mail) {
    const m = body.mail;
    const host = str(m.host);
    const username = str(m.username);
    const fromEmail = str(m.fromEmail);
    const existing = await prisma.mailSetting.findFirst({ where: { institutionId } });
    const password = str(m.password) || existing?.password || "";
    if (!host || !fromEmail || !password) {
      return NextResponse.json({ error: "MAIL_FIELDS_REQUIRED" }, { status: 400 });
    }
    await prisma.mailSetting.upsert({
      where: { institutionId },
      create: {
        scope: "INSTITUTION",
        institutionId,
        host,
        port: num(m.port, 587),
        secure: m.secure !== false,
        username,
        password,
        fromEmail,
        fromName: str(m.fromName, "Increlog EMS"),
        active: m.active !== false,
      },
      update: {
        host,
        port: num(m.port, 587),
        secure: m.secure !== false,
        username,
        ...(str(m.password) ? { password: str(m.password) } : {}),
        fromEmail,
        fromName: str(m.fromName, "Increlog EMS"),
        active: m.active !== false,
      },
    });
  }

  if (body.sms) {
    const s = body.sms;
    const apiUrl = str(s.apiUrl);
    if (!apiUrl) {
      return NextResponse.json({ error: "SMS_FIELDS_REQUIRED" }, { status: 400 });
    }
    const existing = await prisma.smsSetting.findFirst({ where: { institutionId } });
    const authPassword = str(s.authPassword) || existing?.authPassword || null;
    await prisma.smsSetting.upsert({
      where: { institutionId },
      create: {
        scope: "INSTITUTION",
        institutionId,
        apiUrl,
        method: str(s.method, "POST") === "GET" ? "GET" : "POST",
        senderId: str(s.senderId) || null,
        authUsername: str(s.authUsername) || null,
        authPassword,
        bodyTemplate: str(s.bodyTemplate) || null,
        headersRaw: str(s.headersRaw) || null,
        active: s.active !== false,
      },
      update: {
        apiUrl,
        method: str(s.method, "POST") === "GET" ? "GET" : "POST",
        senderId: str(s.senderId) || null,
        authUsername: str(s.authUsername) || null,
        ...(str(s.authPassword) ? { authPassword: str(s.authPassword) } : {}),
        bodyTemplate: str(s.bodyTemplate) || null,
        headersRaw: str(s.headersRaw) || null,
        active: s.active !== false,
      },
    });
  }

  if (body.whatsapp) {
    const w = body.whatsapp;
    const apiUrl = str(w.apiUrl);
    if (!apiUrl) {
      return NextResponse.json({ error: "WHATSAPP_FIELDS_REQUIRED" }, { status: 400 });
    }
    const existing = await prisma.whatsappSetting.findFirst({ where: { institutionId } });
    const authToken = str(w.authToken) || existing?.authToken || null;
    await prisma.whatsappSetting.upsert({
      where: { institutionId },
      create: {
        scope: "INSTITUTION",
        institutionId,
        apiUrl,
        method: str(w.method, "POST") === "GET" ? "GET" : "POST",
        senderId: str(w.senderId) || null,
        authToken,
        bodyTemplate: str(w.bodyTemplate) || null,
        headersRaw: str(w.headersRaw) || null,
        active: w.active !== false,
      },
      update: {
        apiUrl,
        method: str(w.method, "POST") === "GET" ? "GET" : "POST",
        senderId: str(w.senderId) || null,
        ...(str(w.authToken) ? { authToken: str(w.authToken) } : {}),
        bodyTemplate: str(w.bodyTemplate) || null,
        headersRaw: str(w.headersRaw) || null,
        active: w.active !== false,
      },
    });
  }

  return NextResponse.json({ ok: true });
}
