// Session validation and family resolver for API routes
// All data routes must use this to validate sessions and get familyId

import { sql } from "@/db";
import { cookies } from "next/headers";

interface SessionData {
  userId: string;
  familyId: string | null;
  familyName: string | null;
  tier: string | null;
}

interface AuthResult {
  success: boolean;
  error?: string;
  status?: number;
  session?: SessionData;
}

/**
 * Validate session cookie and resolve family information
 * Use this at the start of every data API route
 */
export async function validateSession(): Promise<AuthResult> {
  try {
    const cookieStore = await cookies();
    const sessionToken = cookieStore.get("tia_session")?.value;

    if (!sessionToken) {
      return { success: false, error: "Not authenticated", status: 401 };
    }

    // Verify session and get family info
    const sessions = await sql`
      SELECT s.user_id, s.expires, fm.family_id as family_id, f.name as family_name, f.tier
      FROM sessions s
      LEFT JOIN family_members fm ON fm.user_id::text = s.user_id::text
      LEFT JOIN families f ON f.id = fm.family_id
      WHERE s.session_token = ${sessionToken}
      AND s.expires > NOW()
      LIMIT 1
    `;

    if (!sessions || sessions.length === 0) {
      return { success: false, error: "Invalid or expired session", status: 401 };
    }

    const session = sessions[0];

    return {
      success: true,
      session: {
        userId: session.user_id,
        familyId: session.family_id,
        familyName: session.family_name,
        tier: session.tier,
      },
    };
  } catch (error) {
    console.error("Session validation error:", error);
    return { success: false, error: "Session validation failed", status: 500 };
  }
}

/**
 * Require authenticated user with a family
 * Use for routes that require family data
 */
export async function requireFamily(): Promise<AuthResult> {
  const auth = await validateSession();

  if (!auth.success) {
    return auth;
  }

  if (!auth.session?.familyId) {
    return { success: false, error: "No family associated with session", status: 403 };
  }

  return auth;
}

/**
 * Require authenticated user who owns a specific resource
 * Use to verify user has access to a resource (e.g., a specific child's data)
 *
 * @param resourceId - The ID of the resource to check
 * @param table - The table name to check ownership in
 * @param resourceLabel - Human-readable label for error messages
 */
export async function requireOwnership(
  resourceId: string,
  table: string,
  resourceLabel: string
): Promise<AuthResult> {
  const auth = await requireFamily();

  if (!auth.success) {
    return auth;
  }

  const familyId = auth.session!.familyId!;

  // Check if resource belongs to user's family
  const result = await sql.unsafe(
    `SELECT id FROM ${table} WHERE id = $1 AND family_id = $2 LIMIT 1`,
    [resourceId, familyId]
  );

  if (!result || result.length === 0) {
    return {
      success: false,
      error: `${resourceLabel} not found or access denied`,
      status: 404,
    };
  }

  return auth;
}

/**
 * Require a specific tier level
 * Use for premium features
 */
export async function requireTier(minTier: "free" | "pro"): Promise<AuthResult> {
  const auth = await requireFamily();

  if (!auth.success) {
    return auth;
  }

  const tier = auth.session?.tier || "free";
  const tierLevels = { free: 0, pro: 1 };
  const userLevel = tierLevels[tier as keyof typeof tierLevels] || 0;
  const requiredLevel = tierLevels[minTier];

  if (userLevel < requiredLevel) {
    return {
      success: false,
      error: `Requires ${minTier} tier or higher`,
      status: 403,
    };
  }

  return auth;
}