import { NextRequest, NextResponse } from "next/server";
import { requireStaffAuth } from "@/lib/staff-auth";
import { prisma } from "@/lib/db";
import { logger } from "@/lib/logger";
import { getDataSource } from "@/lib/data-source";

/**
 * GET /api/staff/users/[id]
 *
 * Get comprehensive user details including:
 * - Basic user information
 * - Login history (last 50 logins)
 * - Admin notes
 * - Billing emails
 * - Audit logs
 * - Subscriptions
 * - Analytics (unique IPs, countries, success rate)
 * - Organization membership (for team members)
 */
export async function GET(
  request: NextRequest,
  { params }: { params: { id: string } },
) {
  // Get params first before any async operations to avoid issues
  const userId = params.id;

  try {
    const staffUser = await requireStaffAuth();
    if (!staffUser) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    logger.debug("Fetching comprehensive details for user", { userId });

    // --- Convex data-source routing (strangler fig) ---
    // User detail view is deeply relational (subscriptions, notes, login_history, audit_logs, etc.)
    // Full Convex routing will be done when all relations are migrated.
    // For now, fetch supplementary login history from Convex if available.
    let convexLoginHistory: any[] | null = null;
    if (getDataSource("auth") === "convex") {
      try {
        const { convexQuery } = await import("@/lib/convex-client");
        convexLoginHistory = (await convexQuery(
          "auth/queries:getLoginHistory",
          {
            userId,
            limit: 50,
          },
        )) as any[] | null;
      } catch (convexErr) {
        logger.warn("Convex login history fetch failed (non-critical)", {
          error: convexErr,
        });
      }
    }
    // --- End Convex routing ---

    // Fetch user with all relations
    const user = await prisma.users.findUnique({
      where: { id: userId },
      include: {
        subscriptions: {
          orderBy: { createdAt: "desc" },
          take: 10,
        },
        admin_notes: {
          orderBy: { createdAt: "desc" },
          take: 50,
        },
        billing_emails: {
          orderBy: { sentAt: "desc" },
          take: 50,
        },
        login_history: {
          orderBy: { createdAt: "desc" },
          take: 50,
        },
        audit_logs: {
          orderBy: { createdAt: "desc" },
          take: 50,
        },
        user_links: {
          orderBy: { sortOrder: "asc" },
        },
        // Organization membership - for team members added to a team
        organizationMemberships: {
          select: {
            id: true,
            role: true,
            joinedAt: true,
            organization: {
              select: {
                id: true,
                name: true,
                owner: {
                  select: {
                    id: true,
                    name: true,
                    email: true,
                  },
                },
              },
            },
          },
        },
        // Organization owned by this user
        ownedOrganization: {
          select: {
            id: true,
            name: true,
            _count: {
              select: {
                members: true,
              },
            },
          },
        },
        _count: {
          select: {
            subscriptions: true,
            admin_notes: true,
            billing_emails: true,
            login_history: true,
            audit_logs: true,
            user_links: true,
          },
        },
      },
    });

    if (!user) {
      return NextResponse.json({ error: "User not found" }, { status: 404 });
    }

    logger.debug("Found user", { userId, email: user.email });

    // Calculate login analytics
    const uniqueIps = new Set(user.login_history.map((l) => l.ipAddress));
    const uniqueCountries = new Set(
      user.login_history
        .map((l) => l.country)
        .filter((c): c is string => c !== null),
    );
    const successfulLogins = user.login_history.filter((l) => l.success).length;
    const failedLogins = user.login_history.filter((l) => !l.success).length;
    const successRate =
      user.login_history.length > 0
        ? (successfulLogins / user.login_history.length) * 100
        : 0;

    // Get most recent login locations
    const recentCountries = user.login_history
      .filter((l) => l.country)
      .slice(0, 10)
      .map((l) => ({
        country: l.country,
        city: l.city,
        timestamp: l.createdAt,
      }));

    // Account status
    const accountStatus = user.isSuspended
      ? "suspended"
      : user.lockedUntil && new Date(user.lockedUntil) > new Date()
        ? "locked"
        : user.isActive
          ? "active"
          : "inactive";

    // Calculate billing totals
    const totalBillingEmails = user.billing_emails.length;
    const paidBillingEmails = user.billing_emails.filter(
      (e) => e.status === "PAID",
    ).length;
    const overdueBillingEmails = user.billing_emails.filter(
      (e) => e.status === "OVERDUE",
    ).length;

    // Determine if user is a team member (added to someone else's organization)
    // vs an owner (owns their own organization or is independent)
    //
    // IMPORTANT: Organization owners are ALSO in organization_members with role "OWNER"
    // So we need to check: is this user in an org membership with a NON-OWNER role?
    // If they have role "OWNER", they are the company owner, not a team member
    const membership = user.organizationMemberships?.[0];
    const isOrgOwner = !!user.ownedOrganization;

    // A user is a team member only if:
    // 1. They have an organization membership AND
    // 2. Their role is NOT "OWNER" (meaning they're ADMIN, STAFF, or MEMBER in someone else's org)
    const isTeamMember = membership && membership.role !== "OWNER";

    // Build team membership info for team members
    let teamMembership = null;
    if (isTeamMember && user.organizationMemberships[0]) {
      const mem = user.organizationMemberships[0];
      teamMembership = {
        organizationId: mem.organization.id,
        organizationName: mem.organization.name,
        role: mem.role,
        joinedAt: mem.joinedAt,
        owner: mem.organization.owner,
      };
    }

    // Build owned organization info for owners
    let ownedOrganization = null;
    if (isOrgOwner && user.ownedOrganization) {
      ownedOrganization = {
        id: user.ownedOrganization.id,
        name: user.ownedOrganization.name,
        memberCount: user.ownedOrganization._count.members,
      };
    }

    // Remove password from response
    const { password, ...userWithoutPassword } = user;
    void password;

    const response = {
      user: {
        ...userWithoutPassword,
        accountStatus,
        // Flag to indicate user type
        isTeamMember,
        isOrgOwner,
        // Team membership info (for team members)
        teamMembership,
        // Owned organization info (for owners)
        ownedOrganization,
      },
      analytics: {
        loginStats: {
          total: user.login_history.length,
          successful: successfulLogins,
          failed: failedLogins,
          successRate: Math.round(successRate * 100) / 100,
          uniqueIps: uniqueIps.size,
          uniqueCountries: uniqueCountries.size,
          recentCountries,
        },
        billingStats: {
          total: totalBillingEmails,
          paid: paidBillingEmails,
          overdue: overdueBillingEmails,
        },
        activityStats: {
          adminNotes: user._count.admin_notes,
          auditLogs: user._count.audit_logs,
          subscriptions: user._count.subscriptions,
        },
      },
    };

    return NextResponse.json(response);
  } catch (error: unknown) {
    // Re-throw redirect errors - these are intentional navigation
    if (error && typeof error === "object" && "digest" in error) {
      const digest = (error as { digest?: string }).digest;
      if (digest?.startsWith("NEXT_REDIRECT")) {
        throw error;
      }
    }

    const errorMessage =
      error instanceof Error ? error.message : "Unknown error";
    logger.error("Failed to fetch user details", error, {
      userId,
      errorMessage,
    });
    return NextResponse.json(
      { error: "Failed to fetch user details", details: errorMessage },
      { status: 500 },
    );
  }
}
