import {
  json,
  type LoaderFunctionArgs,
  type ActionFunctionArgs,
} from "@remix-run/node";
import { useLoaderData, useFetcher } from "@remix-run/react";
import { requireUser, requireWorkpace } from "~/services/session.server";
import { getUsageSummary } from "~/services/billing.server";
import {
  createCheckoutSession,
  createBillingPortalSession,
  downgradeSubscription,
} from "~/services/stripe.server";
import { CreditCard, TrendingUp, Calendar, AlertCircle } from "lucide-react";
import { Button } from "~/components/ui/button";
import { Card } from "~/components/ui/card";
import { Badge } from "~/components/ui/badge";
import { Progress } from "~/components/ui/progress";
import { useState } from "react";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "~/components/ui/dialog";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "~/components/ui/alert-dialog";
import { prisma } from "~/db.server";
import { isBillingEnabled } from "~/config/billing.server";

export const loader = async ({ request }: LoaderFunctionArgs) => {
  const user = await requireUser(request);
  const workspace = await requireWorkpace(request);

  // Get usage summary
  const usageSummary = await getUsageSummary(workspace.id);

  // Get billing history
  const subscription = await prisma.subscription.findUnique({
    where: { workspaceId: workspace.id },
    include: {
      BillingHistory: {
        orderBy: { createdAt: "desc" },
        take: 10,
      },
    },
  });

  const billingEnabled = isBillingEnabled();

  return json({
    user,
    workspace,
    usageSummary: usageSummary as any,
    billingHistory: subscription?.BillingHistory || [],
    billingEnabled,
    subscription: subscription
      ? {
          status: subscription.status,
          planType: subscription.planType,
          currentPeriodEnd: subscription.currentPeriodEnd,
        }
      : null,
  });
};

export const action = async ({ request }: ActionFunctionArgs) => {
  const user = await requireUser(request);
  const workspace = await requireWorkpace(request);
  const formData = await request.formData();
  const intent = formData.get("intent");

  if (intent === "upgrade") {
    const planType = formData.get("planType") as "PRO" | "MAX";
    const origin = new URL(request.url).origin;

    const checkoutUrl = await createCheckoutSession({
      workspaceId: workspace.id,
      planType,
      email: user.email,
      successUrl: `${origin}/settings/billing?success=true`,
      cancelUrl: `${origin}/settings/billing?canceled=true`,
    });

    return json({ checkoutUrl });
  }

  if (intent === "manage") {
    const origin = new URL(request.url).origin;

    const portalUrl = await createBillingPortalSession({
      workspaceId: workspace.id,
      returnUrl: `${origin}/settings/billing`,
    });

    return json({ portalUrl });
  }

  if (intent === "downgrade") {
    const targetPlan = formData.get("planType") as "FREE" | "PRO";

    // Downgrade subscription - keeps credits until period end, then switches to new plan
    await downgradeSubscription({
      workspaceId: workspace.id,
      newPlanType: targetPlan,
    });

    return json({
      success: true,
      message: `Successfully scheduled downgrade to ${targetPlan}. Your current credits will remain available until the end of your billing period.`,
    });
  }

  return json({ error: "Invalid intent" }, { status: 400 });
};

export default function BillingSettings() {
  const { usageSummary, billingHistory, billingEnabled, subscription } =
    useLoaderData<typeof loader>();
  const fetcher = useFetcher<typeof action>();
  const [showPlansModal, setShowPlansModal] = useState(false);
  const [showDowngradeDialog, setShowDowngradeDialog] = useState(false);
  const [targetDowngradePlan, setTargetDowngradePlan] = useState<
    "FREE" | "PRO" | null
  >(null);

  // Handle upgrade action
  const handleUpgrade = (planType: "PRO" | "MAX") => {
    fetcher.submit({ intent: "upgrade", planType }, { method: "POST" });
  };

  // Handle downgrade action
  const handleDowngrade = (planType: "FREE" | "PRO") => {
    setTargetDowngradePlan(planType);
    setShowDowngradeDialog(true);
  };

  // Confirm and execute downgrade
  const confirmDowngrade = () => {
    if (targetDowngradePlan) {
      fetcher.submit(
        { intent: "downgrade", planType: targetDowngradePlan },
        { method: "POST" },
      );
      setShowDowngradeDialog(false);
      setTargetDowngradePlan(null);
    }
  };

  // Determine if plan is upgrade, downgrade, or current
  const getPlanAction = (targetPlan: "FREE" | "PRO" | "MAX") => {
    const planOrder = { FREE: 0, PRO: 1, MAX: 2 };
    const currentOrder =
      planOrder[usageSummary.plan.type as keyof typeof planOrder];
    const targetOrder = planOrder[targetPlan];

    if (currentOrder === targetOrder) return "current";
    if (targetOrder > currentOrder) return "upgrade";
    return "downgrade";
  };

  // Handle plan selection
  const handlePlanSelect = (planType: "FREE" | "PRO" | "MAX") => {
    const action = getPlanAction(planType);

    if (action === "current") return;

    if (action === "upgrade") {
      handleUpgrade(planType as "PRO" | "MAX");
    } else {
      handleDowngrade(planType as "FREE" | "PRO");
    }
  };

  // Show success message after downgrade
  if (fetcher.data && "success" in fetcher.data && fetcher.data.success) {
    // Close modal and show message
    setTimeout(() => {
      setShowPlansModal(false);
      window.location.reload(); // Reload to show updated plan info
    }, 1500);
  }

  // Redirect to checkout/portal when URL is received
  if (
    fetcher.data &&
    "checkoutUrl" in fetcher.data &&
    fetcher.data.checkoutUrl
  ) {
    window.location.href = fetcher.data.checkoutUrl;
  }

  if (fetcher.data && "portalUrl" in fetcher.data && fetcher.data.portalUrl) {
    window.location.href = fetcher.data.portalUrl;
  }

  if (!billingEnabled) {
    return (
      <div className="p-8">
        <div className="mb-8">
          <h1 className="text-2xl font-bold">Billing</h1>
          <p className="text-muted-foreground">
            Billing is disabled in self-hosted mode. You have unlimited usage.
          </p>
        </div>
      </div>
    );
  }

  if (!usageSummary) {
    return (
      <div className="p-8">
        <div className="mb-8">
          <h1 className="text-2xl font-bold">Billing</h1>
          <p className="text-muted-foreground">
            No billing information available.
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="p-8">
      {/* Header */}
      <div className="mb-8">
        <h1 className="text-2xl font-bold">Billing</h1>
        <p className="text-muted-foreground">
          Manage your subscription, usage, and billing history
        </p>
      </div>

      {/* Usage Section */}
      <div className="mb-8">
        <h2 className="mb-4 text-lg font-semibold">Current Usage</h2>

        <div className="grid gap-4 md:grid-cols-3">
          {/* Credits Card */}
          <Card className="p-6">
            <div className="mb-2 flex items-center justify-between">
              <span className="text-muted-foreground text-sm">Credits</span>
              <CreditCard className="text-muted-foreground h-4 w-4" />
            </div>
            <div className="mb-2">
              <span className="text-3xl font-bold">
                {usageSummary.credits.available}
              </span>
              <span className="text-muted-foreground">
                {" "}
                / {usageSummary.credits.monthly}
              </span>
            </div>
            <Progress
              segments={[{ value: 100 - usageSummary.credits.percentageUsed }]}
              className="mb-2"
            />
            <p className="text-muted-foreground text-xs">
              {usageSummary.credits.percentageUsed}% used this period
            </p>
          </Card>

          {/* Usage Breakdown */}
          <Card className="p-6">
            <div className="mb-2 flex items-center justify-between">
              <span className="text-muted-foreground text-sm">
                Usage Breakdown
              </span>
              <TrendingUp className="text-muted-foreground h-4 w-4" />
            </div>
            <div className="space-y-2">
              <div className="flex justify-between text-sm">
                <span className="text-muted-foreground">Facts</span>
                <span className="font-medium">
                  {usageSummary.usage.episodes}
                </span>
              </div>
              <div className="flex justify-between text-sm">
                <span className="text-muted-foreground">Searches</span>
                <span className="font-medium">
                  {usageSummary.usage.searches}
                </span>
              </div>
              <div className="flex justify-between text-sm">
                <span className="text-muted-foreground">Chat</span>
                <span className="font-medium">{usageSummary.usage.chat}</span>
              </div>
            </div>
          </Card>

          {/* Billing Cycle */}
          <Card className="p-6">
            <div className="mb-2 flex items-center justify-between">
              <span className="text-muted-foreground text-sm">
                Billing Cycle
              </span>
              <Calendar className="text-muted-foreground h-4 w-4" />
            </div>
            <div className="mb-2">
              <span className="text-3xl font-bold">
                {usageSummary.billingCycle.daysRemaining}
              </span>
              <span className="text-muted-foreground"> days left</span>
            </div>
            <p className="text-muted-foreground text-xs">
              Resets on{" "}
              {new Date(usageSummary.billingCycle.end).toLocaleDateString()}
            </p>
          </Card>
        </div>

        {/* Overage Warning */}
        {usageSummary.credits.overage > 0 && (
          <Card className="mt-4 border-orange-500 bg-orange-50 p-4 dark:bg-orange-950">
            <div className="flex items-start gap-3">
              <AlertCircle className="h-5 w-5 text-orange-600 dark:text-orange-400" />
              <div>
                <h3 className="font-semibold text-orange-900 dark:text-orange-100">
                  Overage Usage Detected
                </h3>
                <p className="text-sm text-orange-700 dark:text-orange-300">
                  You've used {usageSummary.credits.overage} additional credits
                  beyond your monthly allocation.
                  {usageSummary.overage.enabled &&
                    usageSummary.overage.pricePerCredit && (
                      <>
                        {" "}
                        This will cost $
                        {(
                          usageSummary.credits.overage *
                          usageSummary.overage.pricePerCredit
                        ).toFixed(2)}{" "}
                        extra this month.
                      </>
                    )}
                </p>
              </div>
            </div>
          </Card>
        )}
      </div>

      {/* Plan Section */}
      <div className="mb-8">
        <div className="mb-4 flex items-center justify-between">
          <h2 className="text-lg font-semibold">Plan</h2>
          <Button variant="secondary" onClick={() => setShowPlansModal(true)}>
            View All Plans
          </Button>
        </div>

        <Card className="p-6">
          <div className="flex items-center justify-between">
            <div>
              <div className="mb-2 flex items-center gap-2">
                <h3 className="text-xl font-bold">{usageSummary.plan.name}</h3>
                <Badge
                  variant={
                    usageSummary.plan.type === "FREE" ? "secondary" : "default"
                  }
                  className="rounded"
                >
                  {usageSummary.plan.type}
                </Badge>
              </div>
              <p className="text-muted-foreground text-sm">
                {usageSummary.credits.monthly} credits/month
                {usageSummary.overage.enabled && (
                  <> + ${usageSummary.overage.pricePerCredit}/credit overage</>
                )}
              </p>
              {subscription?.status === "CANCELED" &&
                subscription.planType !== "FREE" && (
                  <div className="mt-3 flex items-start gap-2 rounded-md bg-orange-50 p-3 dark:bg-orange-950">
                    <AlertCircle className="mt-0.5 h-4 w-4 text-orange-600 dark:text-orange-400" />
                    <p className="text-sm text-orange-700 dark:text-orange-300">
                      Downgrading to FREE plan on{" "}
                      <strong>
                        {new Date(
                          subscription.currentPeriodEnd,
                        ).toLocaleDateString()}
                      </strong>
                      . Your current credits and plan will remain active until
                      then.
                    </p>
                  </div>
                )}
            </div>
          </div>
        </Card>
      </div>

      {/* Invoices Section */}
      <div className="mb-8">
        <h2 className="mb-4 text-lg font-semibold">Invoices</h2>

        {billingHistory.length === 0 ? (
          <Card className="p-6">
            <p className="text-muted-foreground text-center">No invoices yet</p>
          </Card>
        ) : (
          <Card>
            <div className="divide-y">
              {billingHistory.map((invoice) => (
                <div
                  key={invoice.id}
                  className="flex items-center justify-between p-4"
                >
                  <div>
                    <p className="font-medium">
                      {new Date(invoice.periodStart).toLocaleDateString()} -{" "}
                      {new Date(invoice.periodEnd).toLocaleDateString()}
                    </p>
                  </div>
                  <div className="text-right">
                    <p className="font-bold">
                      ${invoice.totalAmount.toFixed(2)}
                    </p>
                    <Badge
                      variant={
                        invoice.stripePaymentStatus === "paid"
                          ? "default"
                          : "destructive"
                      }
                      className="rounded"
                    >
                      {invoice.stripePaymentStatus || "pending"}
                    </Badge>
                  </div>
                </div>
              ))}
            </div>
          </Card>
        )}
      </div>

      {/* Plans Modal */}
      <Dialog open={showPlansModal} onOpenChange={setShowPlansModal}>
        <DialogContent className="max-w-5xl p-6">
          <DialogHeader>
            <DialogTitle>Choose Your CORE Plan</DialogTitle>
            <DialogDescription>
              Unlock the power of portable memory
            </DialogDescription>
          </DialogHeader>

          <div className="grid gap-6 p-6 md:grid-cols-3">
            {/* Free Plan */}
            <Card className="p-6">
              <div className="mb-4">
                <h3 className="text-xl font-bold">Free</h3>
                <p className="text-muted-foreground text-sm">
                  No credit card required
                </p>
              </div>
              <div className="mb-6">
                <span className="text-4xl font-bold">$0</span>
                <span className="text-muted-foreground">/month</span>
              </div>
              <ul className="mb-6 space-y-2 text-sm">
                <li className="flex items-start gap-2">
                  <span>Memory facts: 3k/mo</span>
                </li>
                <li className="flex items-start gap-2">
                  <span>NO USAGE BASED</span>
                </li>
              </ul>
              <Button
                className="w-full"
                variant="outline"
                disabled={
                  usageSummary.plan.type === "FREE" ||
                  fetcher.state === "submitting"
                }
                onClick={() => handlePlanSelect("FREE")}
              >
                {usageSummary.plan.type === "FREE"
                  ? "Current Plan"
                  : getPlanAction("FREE") === "downgrade"
                    ? "Downgrade to Free"
                    : "Try CORE for free"}
              </Button>
            </Card>

            {/* Pro Plan */}
            <Card className="border-primary p-6">
              <div className="mb-4">
                <h3 className="text-xl font-bold">Pro</h3>
                <p className="text-muted-foreground text-sm">
                  For Everyday Productivity
                </p>
              </div>
              <div className="mb-6">
                <span className="text-4xl font-bold">$19</span>
                <span className="text-muted-foreground">/month</span>
              </div>
              <ul className="mb-6 space-y-2 text-sm">
                <li className="flex items-start gap-2">
                  <span>Memory facts: 15k/mo</span>
                </li>
                <li className="flex items-start gap-2">
                  <span>$0.299 /1K ADDITIONAL FACTS</span>
                </li>
              </ul>
              <Button
                className="w-full"
                disabled={
                  usageSummary.plan.type === "PRO" ||
                  fetcher.state === "submitting"
                }
                onClick={() => handlePlanSelect("PRO")}
              >
                {usageSummary.plan.type === "PRO"
                  ? "Current Plan"
                  : getPlanAction("PRO") === "upgrade"
                    ? "Upgrade to PRO"
                    : "Downgrade to PRO"}
              </Button>
            </Card>

            {/* Max Plan */}
            <Card className="p-6">
              <div className="mb-4">
                <h3 className="text-xl font-bold">Max</h3>
                <p className="text-muted-foreground text-sm">
                  Get the most out of CORE
                </p>
              </div>
              <div className="mb-6">
                <span className="text-4xl font-bold">$99</span>
                <span className="text-muted-foreground">/month</span>
              </div>
              <ul className="mb-6 space-y-2 text-sm">
                <li className="flex items-start gap-2">
                  <span>Memory facts: 100k/mo</span>
                </li>
                <li className="flex items-start gap-2">
                  <span>$0.249 /1K ADDITIONAL FACTS</span>
                </li>
              </ul>
              <Button
                className="w-full"
                disabled={
                  usageSummary.plan.type === "MAX" ||
                  fetcher.state === "submitting"
                }
                onClick={() => handlePlanSelect("MAX")}
              >
                {usageSummary.plan.type === "MAX"
                  ? "Current Plan"
                  : "Upgrade to MAX"}
              </Button>
            </Card>
          </div>
        </DialogContent>
      </Dialog>

      {/* Downgrade Confirmation Dialog */}
      <AlertDialog
        open={showDowngradeDialog}
        onOpenChange={setShowDowngradeDialog}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Confirm Downgrade</AlertDialogTitle>
            <AlertDialogDescription>
              Are you sure you want to downgrade to the{" "}
              <strong>{targetDowngradePlan}</strong> plan? Your current credits
              will remain available until the end of your billing period, then
              you'll be switched to the {targetDowngradePlan} plan.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={confirmDowngrade}>
              Continue
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
