import { NextResponse } from "next/server";
import { getCurrentUser } from "@/lib/auth";
import { prisma } from "@/lib/prisma";

/**
 * GET /api/me
 *
 * Returns the current user with their org and brands.
 * If this is a brand-new Clerk user, it:
 *   1. Creates a User record in the database
 *   2. Creates a default Organization
 *   3. Makes the user the owner
 *
 * The frontend should call this after Clerk sign-in to bootstrap data.
 */
export const dynamic = "force-dynamic";

export async function GET() {
  const user = await getCurrentUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  console.info("[/api/me]", { userId: user.id, email: user.email, memberships: user.memberships.length });

  // If user has no org yet, check if they have an OrgMembership by
  // a different userId (ID mismatch) before creating a brand-new org.
  if (user.memberships.length === 0) {
    // Self-healing: find OrgMembership via email lookup.
    // Try two paths — via User relation AND directly by userId
    // to catch cases where the OrgMembership.userId points to a
    // stale/deleted User record that can't be joined.
    let existingMembership = await prisma.orgMembership.findFirst({
      where: { user: { email: user.email } },
      include: {
        organization: {
          include: { brands: { include: { websites: true, profile: true }, orderBy: { createdAt: "desc" } } },
        },
      },
    });

    // Fallback: find any OrgMembership where the organization has
    // brands — this catches the case where OrgMembership.userId
    // points to a non-existent User (relation join fails).
    if (!existingMembership) {
      // Find all orgs that have brands — one of them is likely the owner's org
      const orgsWithBrands = await prisma.organization.findMany({
        where: { brands: { some: {} } },
        select: {
          id: true,
          memberships: { select: { id: true, userId: true, role: true } },
        },
      });
      for (const org of orgsWithBrands) {
        // Check if any membership's userId is associated with this email
        for (const m of org.memberships) {
          const memberUser = await prisma.user.findUnique({
            where: { id: m.userId },
            select: { email: true },
          });
          if (memberUser?.email === user.email) {
            console.warn("[/api/me] Found membership via org scan", { userId: user.id, memberUserId: m.userId, orgId: org.id });
            // Repair: update the membership to use the current user ID
            await prisma.orgMembership.update({
              where: { id: m.id },
              data: { userId: user.id },
            });
            const repairedUser = await prisma.user.findUnique({
              where: { id: user.id },
              include: { memberships: { include: { organization: { include: { brands: { include: { websites: true, profile: true }, orderBy: { createdAt: "desc" } } } } } } },
            });
            return NextResponse.json(formatUserResponse(repairedUser!));
          }
        }
      }

      // Last resort: the owner might have NO membership at all.
      // Create one for the first org that has brands.
      if (orgsWithBrands.length > 0) {
        console.warn("[/api/me] No membership found anywhere — creating owner membership", { userId: user.id, email: user.email });
        await prisma.orgMembership.create({
          data: { userId: user.id, orgId: orgsWithBrands[0].id, role: "owner" },
        });
        const repairedUser = await prisma.user.findUnique({
          where: { id: user.id },
          include: { memberships: { include: { organization: { include: { brands: { include: { websites: true, profile: true }, orderBy: { createdAt: "desc" } } } } } } },
        });
        return NextResponse.json(formatUserResponse(repairedUser!));
      }
    }

    if (existingMembership) {
      console.warn("[/api/me] Found orphaned membership via email lookup — repairing", { userId: user.id, membershipUserId: existingMembership.userId, email: user.email });
      await prisma.orgMembership.update({
        where: { id: existingMembership.id },
        data: { userId: user.id },
      });
      const repairedUser = await prisma.user.findUnique({
        where: { id: user.id },
        include: { memberships: { include: { organization: { include: { brands: { include: { websites: true, profile: true }, orderBy: { createdAt: "desc" } } } } } } },
      });
      return NextResponse.json(formatUserResponse(repairedUser!));
    }
    const orgName = `${user.name || "My"}'s Workspace`;
    const slug = orgName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") + "-" + Date.now().toString(36);

    const org = await prisma.organization.create({
      data: {
        name: orgName,
        slug,
        memberships: {
          create: { userId: user.id, role: "owner" },
        },
      },
    });

    // Re-fetch user with the new membership
    const updatedUser = await prisma.user.findUnique({
      where: { id: user.id },
      include: {
        memberships: {
          include: {
            organization: {
              include: {
                brands: {
                  include: { websites: true, profile: true },
                },
              },
            },
          },
        },
      },
    });

    return NextResponse.json(formatUserResponse(updatedUser!));
  }

  // User already has orgs — fetch full data
  const fullUser = await prisma.user.findUnique({
    where: { id: user.id },
    include: {
      memberships: {
        include: {
          organization: {
            include: {
              brands: {
                include: { websites: true, profile: true },
                orderBy: { createdAt: "desc" },
              },
            },
          },
        },
      },
    },
  });

  return NextResponse.json(formatUserResponse(fullUser!));
}

function formatUserResponse(user: {
  id: string;
  name: string | null;
  email: string;
  image: string | null;
  memberships: Array<{
    role: string;
    organization: {
      id: string;
      name: string;
      slug: string;
      plan: string;
      brands: Array<Record<string, unknown>>;
    };
  }>;
}) {
  return {
    user: {
      id: user.id,
      name: user.name,
      email: user.email,
      image: user.image,
    },
    organizations: user.memberships.map((m) => ({
      id: m.organization.id,
      name: m.organization.name,
      slug: m.organization.slug,
      plan: m.organization.plan,
      role: m.role,
      brands: m.organization.brands,
    })),
  };
}
