"use server";

import { revalidatePath } from "next/cache";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth/auth-options";
import { initDb } from "@/lib/db";
import { getStripe } from "@/lib/stripe/stripe-client";
import {
  getStripePriceId,
  isStripeConfigured,
  PLAN_DEFINITIONS,
} from "@/config/plans";
import {
  applyPlanToWorkspace,
  getBillingPageData,
} from "@/lib/queries/billing-queries";
import type { ActionResult } from "@/lib/actions/auth";
import type { BillingCycle, PlanTier } from "@/types";

async function requireBillingWorkspace() {
  const session = await getServerSession(authOptions);
  if (!session?.user?.id || !session.user.workspaceId) {
    return null;
  }
  return {
    userId: session.user.id,
    workspaceId: session.user.workspaceId,
  };
}

function appBaseUrl(): string {
  return (
    process.env.NEXT_PUBLIC_APP_URL ??
    process.env.NEXTAUTH_URL ??
    "http://localhost:3000"
  );
}

/** Start Stripe Checkout for Pro upgrade. */
export async function createCheckoutSession(input: {
  planTier: PlanTier;
  billingCycle: BillingCycle;
}): Promise<ActionResult<{ url: string }>> {
  const ctx = await requireBillingWorkspace();
  if (!ctx) return { success: false, error: "Not authenticated" };

  if (input.planTier !== "pro") {
    return {
      success: false,
      error: "Enterprise plans require contacting sales.",
    };
  }

  const stripe = getStripe();
  if (!stripe || !isStripeConfigured()) {
    return {
      success: false,
      error: "Stripe is not configured. Contact support to upgrade.",
    };
  }

  const priceId = getStripePriceId(input.planTier, input.billingCycle);
  if (!priceId) {
    return {
      success: false,
      error: "Stripe price ID missing. Set STRIPE_PRICE_PRO_* in .env.",
    };
  }

  const { Workspace } = initDb();
  const workspace = await Workspace.findByPk(ctx.workspaceId);
  if (!workspace) return { success: false, error: "Workspace not found" };

  let customerId = workspace.stripeCustomerId;
  if (!customerId) {
    const customer = await stripe.customers.create({
      name: workspace.name,
      metadata: { workspaceId: workspace.id },
    });
    customerId = customer.id;
    await workspace.update({ stripeCustomerId: customerId });
  }

  const base = appBaseUrl();
  const session = await stripe.checkout.sessions.create({
    mode: "subscription",
    customer: customerId,
    line_items: [{ price: priceId, quantity: 1 }],
    success_url: `${base}/app/billing?success=1`,
    cancel_url: `${base}/app/billing?canceled=1`,
    metadata: {
      workspaceId: workspace.id,
      planTier: input.planTier,
      billingCycle: input.billingCycle,
    },
    subscription_data: {
      metadata: {
        workspaceId: workspace.id,
        planTier: input.planTier,
      },
    },
  });

  if (!session.url) {
    return { success: false, error: "Failed to create checkout session" };
  }

  return { success: true, data: { url: session.url } };
}

/** Open Stripe Customer Portal for subscription management. */
export async function createBillingPortalSession(): Promise<
  ActionResult<{ url: string }>
> {
  const ctx = await requireBillingWorkspace();
  if (!ctx) return { success: false, error: "Not authenticated" };

  const stripe = getStripe();
  if (!stripe || !isStripeConfigured()) {
    return { success: false, error: "Stripe is not configured." };
  }

  const { Workspace } = initDb();
  const workspace = await Workspace.findByPk(ctx.workspaceId);
  if (!workspace?.stripeCustomerId) {
    return { success: false, error: "No billing account on file." };
  }

  const portal = await stripe.billingPortal.sessions.create({
    customer: workspace.stripeCustomerId,
    return_url: `${appBaseUrl()}/app/billing`,
  });

  return { success: true, data: { url: portal.url } };
}

/** Downgrade to free (local — cancels Stripe sub via portal in production). */
export async function downgradeToFree(): Promise<ActionResult> {
  const ctx = await requireBillingWorkspace();
  if (!ctx) return { success: false, error: "Not authenticated" };

  const { Workspace, AuditLog } = initDb();
  const workspace = await Workspace.findByPk(ctx.workspaceId);
  if (!workspace) return { success: false, error: "Workspace not found" };

  const stripe = getStripe();
  if (workspace.stripeSubscriptionId && stripe) {
    try {
      await stripe.subscriptions.cancel(workspace.stripeSubscriptionId);
    } catch {
      return {
        success: false,
        error: "Could not cancel subscription. Use Manage subscription in billing.",
      };
    }
  }

  await applyPlanToWorkspace(ctx.workspaceId, "free");
  await workspace.update({ stripeSubscriptionId: null });

  await AuditLog.create({
    actorUserId: ctx.userId,
    workspaceId: ctx.workspaceId,
    action: "billing.downgraded",
    metadata: { planTier: "free" },
  });

  revalidatePath("/app/billing");
  return { success: true };
}

export async function getBillingContext() {
  const ctx = await requireBillingWorkspace();
  if (!ctx) return null;
  return getBillingPageData(ctx.workspaceId);
}

/** Display helper for billing UI. */
export async function getPlanCatalog() {
  return PLAN_DEFINITIONS;
}
