/**
 * Subscription Status API
 * GET - Check if the current user has an active subscription
 *
 * All data access goes through Convex. No Prisma fallback.
 */

import { NextRequest } from "next/server";
import { auth } from "@/lib/auth";
import { APIResponse } from "@/lib/utils/api-response.util";
import { getStaffSubscription } from "@/lib/utils/permissions";
import type { SubscriptionStatusResponse } from "@/lib/types/subscription.types";
import { getAuthenticatedEmail } from "@/lib/utils/auth-helpers.util";
import { convexQuery } from "@/lib/convex-client";

const ACTIVE_SUBSCRIPTION_STATUSES = new Set([
  "active",
  "trialing",
  "past_due",
]);

interface ConvexUser {
  _id: string;
  prismaId?: string;
  appUserId?: string;
  email: string;
  name?: string;
  role?: string;
  stripeCustomerId?: string;
  selectedPackage?: string;
}

interface ConvexSubscription {
  _id: string;
  tierId?: string;
  status: string;
  billingPeriod?: string;
  currentPeriodEnd?: number;
  trialEndsAt?: number;
  cancelAtPeriodEnd?: boolean;
  setupFeePaid?: boolean;
}

/**
 * GET /api/subscription/status
 *
 * Check if the current user has an active subscription.
 * Returns subscription details and payment status.
 */
export async function GET(request: NextRequest) {
  try {
    const userEmail = await getAuthenticatedEmail(request, auth);
    if (!userEmail) {
      return APIResponse.unauthorized("Authentication required");
    }

    // Fetch user from Convex
    const convexUser = await convexQuery<ConvexUser>(
      "auth/queries:getUserByEmail",
      { email: userEmail.toLowerCase() },
    );

    if (!convexUser) {
      return APIResponse.unauthorized("User not found");
    }

    const userId =
      convexUser.prismaId || convexUser.appUserId || convexUser._id;

    // Staff members don't need subscriptions
    if (
      convexUser.role &&
      ["STAFF", "ADMIN", "SUPER_ADMIN"].includes(convexUser.role)
    ) {
      const response: SubscriptionStatusResponse = {
        hasActiveSubscription: true,
        needsPayment: false,
        subscription: getStaffSubscription(),
        user: {
          id: userId,
          email: convexUser.email,
          name: convexUser.name || null,
          stripeCustomerId: convexUser.stripeCustomerId || null,
        },
      };

      return APIResponse.success(response);
    }

    // Check organization - if team member, use owner's subscription
    const orgState = await convexQuery<Record<string, unknown>>(
      "organizations/queries:getOrganizationStateByUserId",
      { userId },
    ).catch(() => null);

    if (orgState) {
      const userRole = orgState.userRole as string | undefined;
      const organization = orgState.organization as
        | Record<string, unknown>
        | undefined;
      const ownerId = organization?.ownerId as string | undefined;

      if (ownerId && ownerId !== userId && userRole !== "OWNER") {
        // Team member - check owner's subscription
        const ownerSub = await convexQuery<ConvexSubscription>(
          "billing/queries:getActiveSubscription",
          { userId: ownerId },
        ).catch(() => null);

        if (ownerSub && ACTIVE_SUBSCRIPTION_STATUSES.has(ownerSub.status)) {
          const response: SubscriptionStatusResponse = {
            hasActiveSubscription: true,
            needsPayment: false,
            subscription: {
              id: ownerSub._id,
              tierId: ownerSub.tierId || "",
              status: ownerSub.status,
              billingPeriod: ownerSub.billingPeriod || "monthly",
              currentPeriodEnd: ownerSub.currentPeriodEnd
                ? new Date(ownerSub.currentPeriodEnd)
                : null,
              trialEndsAt: ownerSub.trialEndsAt
                ? new Date(ownerSub.trialEndsAt)
                : null,
              cancelAtPeriodEnd: ownerSub.cancelAtPeriodEnd ?? false,
              setupFeePaid: ownerSub.setupFeePaid ?? false,
            },
            user: {
              id: userId,
              email: convexUser.email,
              name: convexUser.name || null,
              stripeCustomerId: convexUser.stripeCustomerId || null,
            },
          };

          return APIResponse.success(response);
        }
      }
    }

    // Check own subscription in Convex — pass all userId formats to handle write/read mismatch
    const sub = await convexQuery<ConvexSubscription>(
      "billing/queries:getActiveSubscription",
      {
        userId,
        prismaId: convexUser.prismaId || undefined,
        appUserId: convexUser.appUserId || undefined,
      },
    ).catch(() => null);

    if (sub) {
      const hasActive = ACTIVE_SUBSCRIPTION_STATUSES.has(sub.status);
      const response: SubscriptionStatusResponse = {
        hasActiveSubscription: hasActive,
        needsPayment: !hasActive,
        subscription: {
          id: sub._id,
          tierId: sub.tierId || "",
          status: sub.status,
          billingPeriod: sub.billingPeriod || "monthly",
          currentPeriodEnd: sub.currentPeriodEnd
            ? new Date(sub.currentPeriodEnd)
            : null,
          trialEndsAt: sub.trialEndsAt ? new Date(sub.trialEndsAt) : null,
          cancelAtPeriodEnd: sub.cancelAtPeriodEnd ?? false,
          setupFeePaid: sub.setupFeePaid ?? false,
        },
        user: {
          id: userId,
          email: convexUser.email,
          name: convexUser.name || null,
          stripeCustomerId: convexUser.stripeCustomerId || null,
        },
      };

      return APIResponse.success(response);
    }

    // No subscription found - check if user has a selected package (pending payment)
    const subscription = convexUser.selectedPackage
      ? {
          id: `pending:${userId}`,
          tierId: convexUser.selectedPackage,
          status: "pending_payment",
          billingPeriod: "monthly",
          currentPeriodEnd: null,
          trialEndsAt: null,
          cancelAtPeriodEnd: false,
          setupFeePaid: false,
        }
      : null;

    const response: SubscriptionStatusResponse = {
      hasActiveSubscription: false,
      needsPayment: true,
      subscription,
      user: {
        id: userId,
        email: convexUser.email,
        name: convexUser.name || null,
        stripeCustomerId: convexUser.stripeCustomerId || null,
      },
    };

    return APIResponse.success(response);
  } catch (error) {
    console.error("[Subscription Status API] Error:", error);
    return APIResponse.error(
      "Failed to fetch subscription status",
      500,
      "INTERNAL_ERROR",
      { message: error instanceof Error ? error.message : "Unknown error" },
    );
  }
}
