import { NextResponse } from "next/server";
import bcrypt from "bcryptjs";
import { prisma } from "@/lib/prisma";
import { INSTITUTION_TYPES } from "@/lib/constants";
import { generateInstitutionCode } from "@/lib/institution-code";
import { sendCentralMail } from "@/lib/central-mail";
import { appBaseUrl, welcomeInstitutionEmail } from "@/lib/email-templates";
import { ensureReferralCode } from "@/lib/referral";

const TYPE_LABELS: Record<string, string> = {
  PRIMARY_AND_HIGH_SCHOOL: "Primary & High School",
  COLLEGE_AND_UNIVERSITY: "College & University",
  COACHING: "Coaching",
  MADRASHA: "Madrasha",
};

export async function POST(req: Request) {
  try {
    const body = await req.json();
    const institutionName = String(body.institutionName ?? "").trim();
    const institutionType = String(body.institutionType ?? "");
    const email = String(body.adminEmail ?? "").trim().toLowerCase();
    const phone = String(body.phone ?? "").trim();
    const address = String(body.address ?? "").trim();
    const district = String(body.district ?? "").trim();
    const subDistrict = String(body.subDistrict ?? "").trim();
    const adminName = String(body.adminName ?? "").trim();
    const password = String(body.password ?? "");

    if (!institutionName || !email || !adminName || password.length < 6) {
      return NextResponse.json({ error: "Missing or invalid fields" }, { status: 400 });
    }
    if (!INSTITUTION_TYPES.includes(institutionType as never)) {
      return NextResponse.json({ error: "Invalid institution type" }, { status: 400 });
    }

    const existingUser = await prisma.user.findUnique({ where: { email } });
    if (existingUser) {
      return NextResponse.json({ error: "EMAIL_EXISTS" }, { status: 409 });
    }
    const existingInstitution = await prisma.institution.findUnique({ where: { email } });
    if (existingInstitution) {
      return NextResponse.json({ error: "EMAIL_EXISTS" }, { status: 409 });
    }

    // optional referral code — must match a subscriber's code (a wrong code is
    // rejected so the registering institution doesn't silently lose the discount)
    const referralCodeInput = String(body.referralCode ?? "").trim().toUpperCase();
    let referredById: number | null = null;
    if (referralCodeInput) {
      const referrer = await prisma.institution.findUnique({
        where: { referralCode: referralCodeInput },
        select: { id: true },
      });
      if (!referrer) {
        return NextResponse.json({ error: "REFERRAL_INVALID" }, { status: 400 });
      }
      referredById = referrer.id;
    }

    const passwordHash = await bcrypt.hash(password, 10);
    const code = await generateInstitutionCode(institutionType as never);

    const institution = await prisma.institution.create({
      data: {
        name: institutionName,
        code,
        type: institutionType as never,
        isGovernment: Boolean(body.isGovernment),
        email,
        phone: phone || "—",
        address: address || "—",
        district: district || null,
        subDistrict: subDistrict || null,
        // optional Bangladesh education-registry identifiers
        eiin: String(body.eiin ?? "").trim() || null,
        ein: String(body.ein ?? "").trim() || null,
        mpoCode: String(body.mpoCode ?? "").trim() || null,
        boardCode: String(body.boardCode ?? "").trim() || null,
        educationBoard: String(body.educationBoard ?? "").trim() || null,
        establishedYear: Number(body.establishedYear) || null,
        postCode: String(body.postCode ?? "").trim() || null,
        status: "PENDING",
        referredById,
        users: {
          create: {
            name: adminName,
            email,
            passwordHash,
            role: "INSTITUTION_ADMIN",
          },
        },
      },
    });
    // every subscriber gets its own referral code to promote the platform
    await ensureReferralCode(institution.id).catch(() => undefined);

    // Thank-you / welcome note to the registering admin — never blocks signup
    try {
      const tpl = welcomeInstitutionEmail({
        toName: adminName,
        institutionName,
        code,
        typeLabel: TYPE_LABELS[institutionType] ?? null,
        district: district || null,
        loginUrl: `${appBaseUrl()}/login`,
      });
      await sendCentralMail({
        to: email,
        subject: tpl.subject,
        html: tpl.html,
        text: tpl.text,
      });
    } catch (err) {
      console.error("welcome-mail-failed", err);
    }

    return NextResponse.json({ success: true });
  } catch {
    return NextResponse.json({ error: "Registration failed" }, { status: 500 });
  }
}
