import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import { db } from "@/app/db/db";
import { userProfiles, user } from "@/app/db/schema/users";
import { eq } from "drizzle-orm";
import { getServerSession } from "next-auth";
import { AuthOptions } from "@/app/api/auth/[...nextauth]/authOptions";

const UserProfileSchema = z.object({
  firstName: z.string().min(1),
  lastName: z.string().min(1),
  userType: z.enum([
    "private_landlord",
    "private_tenant",
    "social_landlord",
    "social_tenant",
    "homeowner",
    "other",
  ]),
  propertyCount: z
    .enum([
      "1",
      "2–5",
      "6–20",
      "21+",
      "1–50",
      "51–100",
      "101–300",
      "301–1000",
      "1000+",
    ])
    .optional(),
  goals: z
    .array(
      z.enum([
        "access_funding",
        "net_zero",
        "improve_condition",
        "save_money",
        "other",
      ])
    )
    .min(1),
  referralSource: z.enum([
    "search",
    "social_media",
    "NRLA",
    "partner",
    "word_of_mouth",
    "other",
  ]),
  nrlaMembershipId: z.string().optional(),
  marketingOptIn: z.boolean().optional(),
  acceptedPrivacy: z.boolean().refine((v) => v === true, {
    message: "You must accept our privacy policy to continue",
  }),
});

export async function POST(req: NextRequest) {
  try {
    const session = await getServerSession(AuthOptions);
    if (!session?.user?.email) {
      return new NextResponse(JSON.stringify({ msg: "Unauthenticated" }), {
        status: 401,
      });
    }

    const body = await req.json();
    const parsed = UserProfileSchema.parse(body);

    // 1️⃣ Get user from DB
    const existingUser = await db.query.user.findFirst({
      where: eq(user.email, session.user.email),
    });
    if (!existingUser) {
      return new NextResponse(JSON.stringify({ msg: "User not found" }), {
        status: 404,
      });
    }

    // 2️⃣ Check if profile already exists
    const existingProfile = await db.query.userProfiles.findFirst({
      where: eq(userProfiles.userId, existingUser.id),
    });

    // Timestamps for policy and marketing
    const now = new Date();
    const acceptedPrivacyAt = parsed.acceptedPrivacy ? now : null;
    const marketingOptInAt = parsed.marketingOptIn ? now : null;

    if (existingProfile) {
      await db
        .update(userProfiles)
        .set({
          firstName: parsed.firstName,
          lastName: parsed.lastName,
          userType: parsed.userType,
          propertyCount: parsed.propertyCount,
          goals: parsed.goals,
          referralSource: parsed.referralSource,
          nrlaMembershipId: parsed.nrlaMembershipId,
          marketingOptIn: parsed.marketingOptIn ?? false,
          acceptedPrivacy: parsed.acceptedPrivacy,
          acceptedPrivacyAt,
          marketingOptInAt,
          updatedAt: now,
        })
        .where(eq(userProfiles.userId, existingUser.id));
    } else {
      await db.insert(userProfiles).values({
        userId: existingUser.id,
        firstName: parsed.firstName,
        lastName: parsed.lastName,
        userType: parsed.userType,
        propertyCount: parsed.propertyCount,
        goals: parsed.goals,
        referralSource: parsed.referralSource,
        nrlaMembershipId: parsed.nrlaMembershipId,
        marketingOptIn: parsed.marketingOptIn ?? false,
        acceptedPrivacy: parsed.acceptedPrivacy,
        acceptedPrivacyAt,
        marketingOptInAt,
      });
    }

    return new NextResponse(JSON.stringify({ msg: "Profile saved" }), {
      status: 200,
    });
  } catch (err) {
    console.error("Error saving user profile:", err);
    if (err instanceof z.ZodError) {
      return new NextResponse(
        JSON.stringify({ msg: "Invalid input", errors: err.flatten() }),
        {
          status: 400,
        }
      );
    }
    return new NextResponse(JSON.stringify({ msg: "Server error" }), {
      status: 500,
    });
  }
}
