import { CheckIcon, XMarkIcon } from "@heroicons/react/20/solid";
import { ArrowDownCircleIcon, ArrowUpCircleIcon } from "@heroicons/react/24/outline";
import { Form, useLocation, useNavigation } from "@remix-run/react";
import { uiComponent } from "@team-plain/typescript-sdk";
import {
  type AddOnPricing,
  type FreePlanDefinition,
  type Limits,
  type PaidPlanDefinition,
  type Plans,
  type SetPlanBody,
  type SubscriptionResult,
} from "@trigger.dev/platform";
import React, { useEffect, useState } from "react";
import { z } from "zod";
import { DefinitionTip } from "~/components/DefinitionTooltip";
import { Feedback } from "~/components/Feedback";
import { Button } from "~/components/primitives/Buttons";
import { CheckboxWithLabel } from "~/components/primitives/Checkbox";
import { DateTime } from "~/components/primitives/DateTime";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTrigger,
} from "~/components/primitives/Dialog";
import { Header2 } from "~/components/primitives/Headers";
import { Paragraph } from "~/components/primitives/Paragraph";
import { Spinner } from "~/components/primitives/Spinner";
import { TextArea } from "~/components/primitives/TextArea";
import { TextLink } from "~/components/primitives/TextLink";
import { prisma } from "~/db.server";
import { redirectWithErrorMessage } from "~/models/message.server";
import { resolveOrgIdFromSlug } from "~/models/organization.server";
import { logger } from "~/services/logger.server";
import { applyPromoCode, bustPromoCreditsCache, setPlan } from "~/services/platform.v3.server";
import { clearPromoCodeCookie, getPromoCodeFromCookie } from "~/services/promoCode.server";
import { dashboardAction } from "~/services/routeBuilders/dashboardBuilder";
import { engine } from "~/v3/runEngine.server";
import { cn } from "~/utils/cn";
import { sendToPlain } from "~/utils/plain.server";
import { formatCurrency } from "~/utils/numberFormatter";
import { EnvironmentLabel } from "~/components/environments/EnvironmentLabel";

const Params = z.object({
  organizationSlug: z.string(),
});

const schema = z.object({
  type: z.enum(["free", "paid"]),
  planCode: z.string().optional(),
  callerPath: z.string(),
  reasons: z.union([z.string(), z.array(z.string())]).optional(),
  message: z.string().optional(),
});

export const action = dashboardAction(
  {
    params: Params,
    context: async (params) => {
      const organizationId = await resolveOrgIdFromSlug(params.organizationSlug);
      return organizationId ? { organizationId } : {};
    },
    authorization: { action: "manage", resource: { type: "billing" } },
  },
  async ({ request, params, user }) => {
    const { organizationSlug } = params;
    const formData = await request.formData();
    const reasons = formData.getAll("reasons");
    const message = formData.get("message");

    const form = schema.parse({
      ...Object.fromEntries(formData),
      reasons,
      message: message || undefined,
    });

    const organization = await prisma.organization.findFirst({
      where: { slug: organizationSlug, members: { some: { userId: user.id } } },
    });

    if (!organization) {
      throw await redirectWithErrorMessage(form.callerPath, request, "Organization not found");
    }

    let payload: SetPlanBody;

    switch (form.type) {
      case "free": {
        try {
          if (reasons.length > 0 || (message && message.toString().trim() !== "")) {
            await sendToPlain({
              userId: user.id,
              email: user.email,
              name: user.name ?? "",
              title: "Plan cancelation feedback",
              components: [
                uiComponent.text({
                  text: `${user.name} (${user.email}) just canceled their plan.`,
                }),
                uiComponent.divider({ spacingSize: "M" }),
                ...(reasons.length > 0
                  ? [
                      uiComponent.spacer({ size: "L" }),
                      uiComponent.text({
                        size: "L",
                        color: "NORMAL",
                        text: "Reasons:",
                      }),
                      uiComponent.text({
                        text: reasons.join(", "),
                      }),
                    ]
                  : []),
                ...(message
                  ? [
                      uiComponent.spacer({ size: "L" }),
                      uiComponent.text({
                        size: "L",
                        color: "NORMAL",
                        text: "Comment:",
                      }),
                      uiComponent.text({
                        text: message.toString(),
                      }),
                    ]
                  : []),
              ],
            });
          }
        } catch (e) {
          logger.error("Failed to submit to Plain the unsubscribe reason", { error: e });
        }
        payload = {
          type: "free" as const,
          userId: user.id,
        };
        break;
      }
      case "paid": {
        if (form.planCode === undefined) {
          throw await redirectWithErrorMessage(form.callerPath, request, "Not a valid plan");
        }
        payload = {
          type: "paid" as const,
          planCode: form.planCode,
          userId: user.id,
        };
        break;
      }
      default: {
        throw new Error("Invalid form type");
      }
    }

    const result = await setPlan(organization, request, form.callerPath, payload, {
      invalidateBillingCache: engine.invalidateBillingCache.bind(engine),
      // Redeem a promo code carried from the /promo landing page. This runs only
      // once the Free plan has actually been provisioned (the grant target), so a
      // failed plan change never burns the one-time code. Best-effort: it must
      // never change the plan-selection outcome.
      onFreePlanProvisioned: async (response) => {
        const promoCode = await getPromoCodeFromCookie(request);
        if (!promoCode) {
          return;
        }
        const applied = await applyPromoCode(organization.id, user.id, promoCode);
        if (applied?.applied) {
          bustPromoCreditsCache(organization.id);
          response.headers.append("Set-Cookie", await clearPromoCodeCookie());
        }
      },
    });

    return result;
  }
);

const pricingDefinitions = {
  usage: {
    title: "Usage",
    content: "The compute cost when tasks are executing.",
  },
  concurrentRuns: {
    title: "Concurrent runs",
    content: "The number of runs that can be executed at the same time.",
  },
  additionalConcurrency: {
    title: "Additional concurrency",
  },
  taskRun: {
    title: "Task runs",
    content: "A single execution of a task.",
  },
  tasks: {
    title: "Tasks",
    content:
      "Tasks are functions that can run for a long time and provide strong resilience to failure.",
  },
  environment: {
    title: "Environments",
    content: "The different environments available for running your tasks.",
  },
  schedules: {
    title: "Schedules",
    content: "You can attach recurring schedules to tasks using cron syntax.",
  },
  additionalSchedules: {
    title: "Additional schedules",
    content: "Then $10/month per 1,000",
  },
  alerts: {
    title: "Alert destination",
    content:
      "A single email address, Slack channel, or webhook URL that you want to send alerts to.",
  },
  realtime: {
    title: "Realtime connections",
    content:
      "Realtime allows you to send the live status and data from your runs to your frontend. This is the number of simultaneous Realtime connections that can be made.",
  },
  additionalRealtimeConnections: {
    title: "Additional Realtime connections",
    content: "Then $10/month per 1000",
  },
  additionalSeats: {
    title: "Additional seats",
    content: "Then $20/month per seat",
  },
  branches: {
    title: "Branches",
    content:
      "Preview branches allow you to test changes before deploying to production. You can have a limited number active at once (but can archive old ones).",
  },
  additionalBranches: {
    title: "Additional branches",
    content: "Then $10/month per branch",
  },
  metricDashboards: {
    title: "Custom dashboards",
    content: "Custom metric dashboards for monitoring and visualizing your task data.",
  },
  additionalDashboards: {
    title: "Additional dashboards",
    content: "Then $10/month per dashboard",
  },
  queryPeriod: {
    title: "Query period",
    content: "The maximum number of days a query can look back when analyzing your task data.",
  },
  hipaaBaa: {
    title: "HIPAA BAA",
    content:
      "A signed Business Associate Agreement (BAA) is required to run tasks that process Protected Health Information (PHI) on Trigger.dev Cloud.",
  },
};

type PricingPlansProps = {
  plans: Plans;
  concurrencyAddOnPricing: AddOnPricing;
  subscription?: SubscriptionResult;
  organizationSlug: string;
  hasPromotedPlan: boolean;
  periodEnd: Date;
};

export function PricingPlans({
  plans,
  concurrencyAddOnPricing,
  subscription,
  organizationSlug,
  hasPromotedPlan,
  periodEnd,
}: PricingPlansProps) {
  return (
    <div className="flex w-full flex-col">
      <div className="flex flex-col gap-3 lg:flex-row">
        <TierFree
          plan={plans.free}
          subscription={subscription}
          organizationSlug={organizationSlug}
          periodEnd={periodEnd}
        />
        <TierHobby
          plan={plans.hobby}
          organizationSlug={organizationSlug}
          subscription={subscription}
          isHighlighted={hasPromotedPlan}
        />
        <TierPro
          plan={plans.pro}
          organizationSlug={organizationSlug}
          subscription={subscription}
          concurrencyAddOnPricing={concurrencyAddOnPricing}
        />
      </div>
      <div className="mt-3">
        <TierEnterprise />
      </div>
    </div>
  );
}

export function TierFree({
  plan,
  subscription,
  organizationSlug,
  periodEnd,
}: {
  plan: FreePlanDefinition;
  subscription?: SubscriptionResult;
  organizationSlug: string;
  periodEnd: Date;
}) {
  const location = useLocation();
  const navigation = useNavigation();
  const formAction = `/resources/orgs/${organizationSlug}/select-plan`;
  const isLoading = navigation.formAction === formAction;
  const [isDialogOpen, setIsDialogOpen] = useState(false);
  const [isLackingFeaturesChecked, setIsLackingFeaturesChecked] = useState(false);

  useEffect(() => {
    setIsDialogOpen(false);
  }, [subscription]);

  return (
    <TierContainer>
      <PricingHeader title={plan.title} cost={0} />
      {subscription?.plan !== undefined &&
      subscription.plan.type !== "free" &&
      subscription.canceledAt === undefined ? (
        <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen} key="cancel">
          <DialogTrigger asChild>
            <div className="my-6">
              <Button variant="secondary/large" fullWidth className="text-md font-medium">
                {`Downgrade to ${plan.title}`}
              </Button>
            </div>
          </DialogTrigger>
          <DialogContent className="sm:max-w-md">
            <Form action={formAction} method="post" id="subscribe">
              <input type="hidden" name="type" value="free" />
              <input type="hidden" name="callerPath" value={location.pathname} />
              <DialogHeader>Downgrade plan?</DialogHeader>
              <div className="flex items-start gap-3 pb-6 pr-2 pt-8">
                <ArrowDownCircleIcon className="size-12 min-w-12 text-error" />
                <Paragraph variant="base/bright" className="text-text-bright">
                  Are you sure you want to downgrade? You will lose access to your current plan's
                  features on{" "}
                  <DateTime includeTime={false} date={new Date(periodEnd.getTime() + 86400000)} />.
                </Paragraph>
              </div>
              <div>
                <div className="mb-4">
                  <Header2 className="mb-1">Why are you thinking of downgrading?</Header2>
                  <ul className="space-y-1">
                    {[
                      "The Free plan is all I need",
                      "Subscription or usage costs too expensive",
                      "Bugs or technical issues",
                      "No longer need the service",
                      "Found a better alternative",
                      "Lacking features I need",
                    ].map((label, index) => (
                      <li key={index}>
                        <CheckboxWithLabel
                          id={`reason-${index + 1}`}
                          name="reasons"
                          value={label}
                          variant="simple"
                          label={label}
                          labelClassName="text-text-dimmed"
                          onChange={(isChecked: boolean) => {
                            if (label === "Lacking features I need") {
                              setIsLackingFeaturesChecked(isChecked);
                            }
                          }}
                        />
                      </li>
                    ))}
                  </ul>
                </div>
                <div>
                  <Header2 className="mb-1">
                    {isLackingFeaturesChecked
                      ? "What features do you need? Or how can we improve?"
                      : "What can we do to improve?"}
                  </Header2>
                  <TextArea id="improvement-suggestions" name="message" />
                </div>
              </div>
              <DialogFooter className="mt-2">
                <Button variant="secondary/medium" onClick={() => setIsDialogOpen(false)}>
                  Dismiss
                </Button>
                <Button
                  variant="danger/medium"
                  disabled={isLoading}
                  LeadingIcon={isLoading ? () => <Spinner color="white" /> : undefined}
                  type="submit"
                >
                  Downgrade plan
                </Button>
              </DialogFooter>
            </Form>
          </DialogContent>
        </Dialog>
      ) : (
        <Form action={formAction} method="post" id="subscribe-verified" className="my-6">
          <input type="hidden" name="type" value="free" />
          <input type="hidden" name="callerPath" value={location.pathname} />
          <Button
            variant="secondary/large"
            type="submit"
            form="subscribe-verified"
            fullWidth
            className="text-md font-medium"
            disabled={
              isLoading ||
              subscription?.plan?.type === plan.type ||
              subscription?.canceledAt !== undefined
            }
            LeadingIcon={
              isLoading && navigation.formData?.get("planCode") === null ? Spinner : undefined
            }
          >
            {subscription?.plan === undefined
              ? "Select plan"
              : subscription.plan.type === "free"
                ? "Current plan"
                : subscription.canceledAt !== undefined
                  ? "Current plan"
                  : "Select plan"}
          </Button>
        </Form>
      )}
      <ul className="flex flex-col gap-2.5">
        <FeatureItem checked>
          <DefinitionTip
            title="Free credits"
            content={`You get $${plan.limits.includedUsage / 100} of compute each month for free.`}
          >
            ${plan.limits.includedUsage / 100} / month free credits
          </DefinitionTip>
        </FeatureItem>
        <ConcurrentRuns limits={plan.limits} />
        <FeatureItem checked>
          Unlimited{" "}
          <DefinitionTip
            title={pricingDefinitions.tasks.title}
            content={pricingDefinitions.tasks.content}
          >
            tasks
          </DefinitionTip>
        </FeatureItem>
        <TeamMembers limits={plan.limits} />
        <Environments limits={plan.limits} />
        <Branches limits={plan.limits} />
        <MetricDashboards limits={plan.limits} />
        <Schedules limits={plan.limits} />
        <LogRetention limits={plan.limits} />
        <QueryPeriod limits={plan.limits} />
        <SupportLevel limits={plan.limits} />
        <Alerts limits={plan.limits} />
        <RealtimeConcurrency limits={plan.limits} />
      </ul>
    </TierContainer>
  );
}

export function TierHobby({
  plan,
  organizationSlug,
  subscription,
  isHighlighted,
}: {
  plan: PaidPlanDefinition;
  organizationSlug: string;
  subscription?: SubscriptionResult;
  isHighlighted: boolean;
}) {
  const location = useLocation();
  const navigation = useNavigation();
  const formAction = `/resources/orgs/${organizationSlug}/select-plan`;
  const isLoading = navigation.formAction === formAction;
  const [isDialogOpen, setIsDialogOpen] = useState(false);

  useEffect(() => {
    setIsDialogOpen(false);
  }, [subscription]);

  return (
    <TierContainer isHighlighted={isHighlighted}>
      <PricingHeader title={plan.title} isHighlighted={isHighlighted} cost={plan.tierPrice} />
      <Form action={formAction} method="post" id="subscribe-hobby" className="py-6">
        <input type="hidden" name="type" value="paid" />
        <input type="hidden" name="planCode" value={plan.code} />
        <input type="hidden" name="callerPath" value={location.pathname} />
        {subscription?.plan !== undefined &&
        subscription.plan.type !== "free" &&
        subscription.canceledAt === undefined &&
        subscription.plan.code !== plan.code ? (
          <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen} key="downgrade">
            <DialogTrigger asChild>
              <Button variant="secondary/large" fullWidth className="text-md font-medium">
                {`Downgrade to ${plan.title}`}
              </Button>
            </DialogTrigger>
            <DialogContent className="sm:max-w-md">
              <DialogHeader>Downgrade plan?</DialogHeader>
              <div className="mb-2 mt-4 flex items-start gap-3">
                <span>
                  <ArrowDownCircleIcon className="size-12 text-blue-500" />
                </span>
                <Paragraph variant="base/bright" className="text-text-bright">
                  By downgrading you will lose access to your current plan's features and your
                  included credits will be reduced.
                </Paragraph>
              </div>
              <DialogFooter>
                <Button variant="secondary/medium" onClick={() => setIsDialogOpen(false)}>
                  Dismiss
                </Button>
                <Button
                  variant="secondary/medium"
                  disabled={isLoading}
                  LeadingIcon={isLoading ? () => <Spinner color="white" /> : undefined}
                  form="subscribe-hobby"
                >
                  {`Downgrade to ${plan.title}`}
                </Button>
              </DialogFooter>
            </DialogContent>
          </Dialog>
        ) : (
          <Button
            variant={isHighlighted ? "primary/large" : "secondary/large"}
            fullWidth
            className="text-md font-medium"
            form="subscribe-hobby"
            disabled={
              isLoading ||
              (subscription?.plan?.code === plan.code && subscription.canceledAt === undefined)
            }
            LeadingIcon={
              isLoading && navigation.formData?.get("planCode") === plan.code ? Spinner : undefined
            }
          >
            {subscription?.plan === undefined
              ? "Select plan"
              : subscription.plan.type === "free" || subscription.canceledAt !== undefined
                ? `Upgrade to ${plan.title}`
                : subscription.plan.code === plan.code
                  ? "Current plan"
                  : `Upgrade to ${plan.title}`}
          </Button>
        )}
      </Form>
      <ul className="flex flex-col gap-2.5">
        <FeatureItem checked>
          <DefinitionTip
            disableHoverableContent={false}
            title="Credits included"
            content={
              <Paragraph variant="small/dimmed" spacing>
                This plan includes ${plan.limits.includedUsage / 100} of compute each month. After
                that's used, tasks keep running and you're billed per our{" "}
                <TextLink target="_blank" to="https://trigger.dev/pricing#computePricing">
                  compute usage rates
                </TextLink>
                .
              </Paragraph>
            }
          >
            ${plan.limits.includedUsage / 100} / month credits included
          </DefinitionTip>
        </FeatureItem>
        <ConcurrentRuns limits={plan.limits} />
        <FeatureItem checked>
          Unlimited{" "}
          <DefinitionTip
            title={pricingDefinitions.tasks.title}
            content={pricingDefinitions.tasks.content}
          >
            tasks
          </DefinitionTip>
        </FeatureItem>
        <TeamMembers limits={plan.limits} />
        <Environments limits={plan.limits} />
        <Branches limits={plan.limits} />
        <MetricDashboards limits={plan.limits} />
        <Schedules limits={plan.limits} />
        <LogRetention limits={plan.limits} />
        <QueryPeriod limits={plan.limits} />
        <SupportLevel limits={plan.limits} />
        <Alerts limits={plan.limits} />
        <RealtimeConcurrency limits={plan.limits} />
        <HIPAAAddOn>
          <Feedback
            defaultValue="hipaa"
            button={
              <span className="cursor-pointer underline decoration-text-faint underline-offset-4 transition hover:decoration-text-bright">
                Request a BAA
              </span>
            }
          />
        </HIPAAAddOn>
      </ul>
    </TierContainer>
  );
}

export function TierPro({
  plan,
  concurrencyAddOnPricing,
  organizationSlug,
  subscription,
}: {
  plan: PaidPlanDefinition;
  concurrencyAddOnPricing: AddOnPricing;
  organizationSlug: string;
  subscription?: SubscriptionResult;
}) {
  const location = useLocation();
  const navigation = useNavigation();
  const formAction = `/resources/orgs/${organizationSlug}/select-plan`;
  const isLoading = navigation.formAction === formAction;
  const [isDialogOpen, setIsDialogOpen] = useState(false);

  useEffect(() => {
    setIsDialogOpen(false);
  }, [subscription]);

  return (
    <TierContainer>
      <PricingHeader title={plan.title} cost={plan.tierPrice} />
      <Form action={formAction} method="post" id="subscribe-pro">
        <div className="py-6">
          <input type="hidden" name="type" value="paid" />
          <input type="hidden" name="planCode" value={plan.code} />
          <input type="hidden" name="callerPath" value={location.pathname} />
          {subscription?.plan !== undefined &&
          subscription?.plan?.type === "paid" &&
          subscription?.plan?.code !== plan.code &&
          subscription.canceledAt === undefined ? (
            <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen} key="upgrade">
              <DialogTrigger asChild>
                <Button variant="secondary/large" fullWidth className="text-md font-medium">
                  {`Upgrade to ${plan.title}`}
                </Button>
              </DialogTrigger>
              <DialogContent className="sm:max-w-md">
                <DialogHeader>Upgrade plan</DialogHeader>
                <div className="mb-2 mt-4 flex items-start gap-3">
                  <span>
                    <ArrowUpCircleIcon className="size-12 text-primary" />
                  </span>
                  <Paragraph variant="base/bright" className="text-text-bright">
                    Upgrade to get instant access to all the Pro features. You will be charged the
                    new plan price for the remainder of this month on a pro rata basis.
                  </Paragraph>
                </div>
                <DialogFooter>
                  <Button variant="secondary/medium" onClick={() => setIsDialogOpen(false)}>
                    Dismiss
                  </Button>
                  <Button
                    variant="primary/medium"
                    disabled={isLoading}
                    LeadingIcon={isLoading ? () => <Spinner color="white" /> : undefined}
                    form="subscribe-pro"
                  >
                    {`Upgrade to ${plan.title}`}
                  </Button>
                </DialogFooter>
              </DialogContent>
            </Dialog>
          ) : (
            <Button
              variant="secondary/large"
              fullWidth
              form="subscribe-pro"
              className="text-md font-medium"
              disabled={
                isLoading ||
                (subscription?.plan?.code === plan.code && subscription.canceledAt === undefined)
              }
              LeadingIcon={
                isLoading && navigation.formData?.get("planCode") === plan.code
                  ? Spinner
                  : undefined
              }
            >
              {subscription?.plan === undefined
                ? "Select plan"
                : subscription.plan.type === "free" || subscription.canceledAt !== undefined
                  ? `Upgrade to ${plan.title}`
                  : subscription.plan.code === plan.code
                    ? "Current plan"
                    : `Upgrade to ${plan.title}`}
            </Button>
          )}
        </div>
      </Form>
      <ul className="flex flex-col gap-2.5">
        <FeatureItem checked>
          <DefinitionTip
            disableHoverableContent={false}
            title="Credits included"
            content={
              <Paragraph variant="small/dimmed" spacing>
                This plan includes ${plan.limits.includedUsage / 100} of compute each month. After
                that's used, tasks keep running and you're billed per our{" "}
                <TextLink target="_blank" to="https://trigger.dev/pricing#computePricing">
                  compute usage rates
                </TextLink>
                .
              </Paragraph>
            }
          >
            ${plan.limits.includedUsage / 100} / month credits included
          </DefinitionTip>
        </FeatureItem>
        <ConcurrentRuns limits={plan.limits}>
          {`Then ${formatCurrency(concurrencyAddOnPricing.centsPerStep / 100, true)}/month per ${
            concurrencyAddOnPricing.stepSize
          }`}
        </ConcurrentRuns>
        <FeatureItem checked>
          Unlimited{" "}
          <DefinitionTip
            title={pricingDefinitions.tasks.title}
            content={pricingDefinitions.tasks.content}
          >
            tasks
          </DefinitionTip>
        </FeatureItem>
        <TeamMembers limits={plan.limits}>{pricingDefinitions.additionalSeats.content}</TeamMembers>
        <Environments limits={plan.limits} />
        <Branches limits={plan.limits}>{pricingDefinitions.additionalBranches.content}</Branches>
        <MetricDashboards limits={plan.limits}>
          {pricingDefinitions.additionalDashboards.content}
        </MetricDashboards>
        <Schedules limits={plan.limits}>{pricingDefinitions.additionalSchedules.content}</Schedules>
        <LogRetention limits={plan.limits} />
        <QueryPeriod limits={plan.limits} />
        <SupportLevel limits={plan.limits} />
        <Alerts limits={plan.limits} />
        <RealtimeConcurrency limits={plan.limits}>
          {pricingDefinitions.additionalRealtimeConnections.content}
        </RealtimeConcurrency>
        <HIPAAAddOn>
          <Feedback
            defaultValue="hipaa"
            button={
              <span className="cursor-pointer underline decoration-text-faint underline-offset-4 transition hover:decoration-text-bright">
                Request a BAA
              </span>
            }
          />
        </HIPAAAddOn>
      </ul>
    </TierContainer>
  );
}

export function TierEnterprise() {
  return (
    <TierContainer>
      <div className="mb-4 flex w-full flex-col items-start justify-between gap-4 lg:flex-row lg:items-center">
        <div className="flex flex-col gap-0.5">
          <h2 className="text-xl font-medium text-text-dimmed">Enterprise</h2>
          <p className="font-sans text-lg font-normal text-text-bright">Tailor a custom plan</p>
        </div>
        <div className="w-full lg:w-auto lg:max-w-64">
          <Feedback
            defaultValue="enterprise"
            button={
              <div className="flex h-10 w-full cursor-pointer items-center justify-center rounded border border-border-bright bg-tertiary px-8 text-base font-medium transition hover:border-border-brighter hover:bg-surface-control">
                <span className="text-center text-text-bright">Contact us</span>
              </div>
            }
          />
        </div>
      </div>
      <div className="flex w-full flex-wrap items-start justify-between gap-2 lg:flex-nowrap">
        <ul className="flex w-full flex-col gap-y-3 lg:gap-y-1">
          <FeatureItem checked checkedColor="bright">
            All Pro plan features +
          </FeatureItem>
          <FeatureItem checked checkedColor="bright">
            Custom log retention
          </FeatureItem>
        </ul>
        <ul className="flex w-full flex-col gap-y-3 lg:gap-y-1">
          <FeatureItem checked checkedColor="bright">
            Priority support
          </FeatureItem>
          <FeatureItem checked checkedColor="bright">
            Role-based access control
          </FeatureItem>
        </ul>
        <ul className="flex w-full flex-col gap-y-3 lg:gap-y-1">
          <FeatureItem checked checkedColor="bright">
            SOC 2 report
          </FeatureItem>
          <FeatureItem checked checkedColor="bright">
            SSO
          </FeatureItem>
        </ul>
        <ul className="flex w-full flex-col gap-y-3 lg:gap-y-1">
          <HIPAAAddOn checkedColor="bright">
            <Feedback
              defaultValue="hipaa"
              button={
                <span className="cursor-pointer underline decoration-text-faint underline-offset-4 transition hover:decoration-text-bright">
                  Request a BAA
                </span>
              }
            />
          </HIPAAAddOn>
        </ul>
      </div>
    </TierContainer>
  );
}

function TierContainer({
  children,
  isHighlighted,
  className,
}: {
  children: React.ReactNode;
  isHighlighted?: boolean;
  className?: string;
}) {
  return (
    <div
      className={cn(
        "flex w-full min-w-64 flex-col p-6",
        isHighlighted ? "border border-indigo-500" : "border border-grid-dimmed",
        className
      )}
    >
      {children}
    </div>
  );
}

function PricingHeader({
  title,
  cost: flatCost,
  isHighlighted,
  per = "/month",
  maximumFractionDigits = 0,
}: {
  title: string;
  cost?: number;
  isHighlighted?: boolean;
  per?: string;
  maximumFractionDigits?: number;
}) {
  const dollarFormatter = new Intl.NumberFormat("en-US", {
    style: "currency",
    currency: "USD",
    maximumFractionDigits,
  });

  return (
    <div className="flex flex-col gap-2">
      <h2
        className={cn(
          "text-xl font-medium",
          isHighlighted ? "text-indigo-500" : "text-text-dimmed"
        )}
      >
        {title}
      </h2>
      {flatCost === 0 || flatCost ? (
        <h3 className="text-4xl font-medium tabular-nums text-text-bright">
          {dollarFormatter.format(flatCost)}
          <span className="ml-1 text-sm font-normal tracking-wide text-text-dimmed">{per}</span>
        </h3>
      ) : (
        <h2 className="text-4xl font-medium">Custom</h2>
      )}
    </div>
  );
}

function FeatureItem({
  checked,
  checkedColor = "primary",
  children,
}: {
  checked?: boolean;
  checkedColor?: "primary" | "bright";
  children: React.ReactNode;
}) {
  return (
    <li className="flex items-start gap-2">
      {checked ? (
        <CheckIcon
          className={cn(
            "mt-0.5 size-4 min-w-4",
            checkedColor === "primary" ? "text-primary" : "text-text-bright"
          )}
        />
      ) : (
        <XMarkIcon className="mt-0.5 size-4 min-w-4 text-text-faint" />
      )}
      <div
        className={cn(
          "font-sans text-sm font-normal",
          checked ? "text-text-bright" : "text-text-dimmed"
        )}
      >
        {children}
      </div>
    </li>
  );
}

function ConcurrentRuns({ limits, children }: { limits: Limits; children?: React.ReactNode }) {
  return (
    <FeatureItem checked>
      <div className="flex flex-col gap-y-0.5">
        <div className="flex items-center gap-1">
          {limits.concurrentRuns.canExceed ? (
            <>
              {limits.concurrentRuns.number}
              {"+"}
            </>
          ) : (
            <>{limits.concurrentRuns.number} </>
          )}
          <DefinitionTip
            title={pricingDefinitions.concurrentRuns.title}
            content={
              <div className="flex flex-col">
                <Paragraph variant="small/dimmed" spacing>
                  {pricingDefinitions.concurrentRuns.content}
                </Paragraph>

                <div className="flex items-center gap-x-1">
                  <EnvironmentLabel environment={{ type: "PRODUCTION" }} />
                  <span>
                    {limits.concurrentRuns.production}
                    {limits.concurrentRuns.canExceed ? "+" : ""}
                  </span>
                </div>
                <div className="flex items-center gap-x-1">
                  <EnvironmentLabel environment={{ type: "STAGING" }} />
                  <span>
                    {limits.concurrentRuns.staging}
                    {limits.concurrentRuns.canExceed ? "+" : ""}
                  </span>
                </div>
                <div className="flex items-center gap-x-1">
                  <EnvironmentLabel environment={{ type: "PREVIEW" }} />
                  <span>
                    {limits.concurrentRuns.preview}
                    {limits.concurrentRuns.canExceed ? "+" : ""}
                  </span>
                </div>
                <div className="flex items-center gap-x-1">
                  <EnvironmentLabel environment={{ type: "DEVELOPMENT" }} />
                  <span>
                    {limits.concurrentRuns.development}
                    {limits.concurrentRuns.canExceed ? "+" : ""}
                  </span>
                </div>
              </div>
            }
          >
            concurrent runs
          </DefinitionTip>
        </div>
        {children && <span className="text-xs text-text-dimmed">{children}</span>}
      </div>
    </FeatureItem>
  );
}

function TeamMembers({ limits, children }: { limits: Limits; children?: React.ReactNode }) {
  return (
    <FeatureItem checked>
      <div className="flex flex-col gap-y-0.5">
        <div className="flex items-center gap-1">
          {limits.teamMembers.number}
          {limits.teamMembers.canExceed ? "+" : ""} team members
        </div>
        {children && <span className="text-xs text-text-dimmed">{children}</span>}
      </div>
    </FeatureItem>
  );
}

function Environments({ limits }: { limits: Limits }) {
  return (
    <FeatureItem checked>
      {limits.hasStagingEnvironment ? "Dev, Preview and Prod" : "Dev and Prod"}{" "}
      <DefinitionTip
        title={pricingDefinitions.environment.title}
        content={pricingDefinitions.environment.content}
      >
        environments
      </DefinitionTip>
    </FeatureItem>
  );
}

function Schedules({ limits, children }: { limits: Limits; children?: React.ReactNode }) {
  return (
    <FeatureItem checked>
      <div className="flex flex-col gap-y-0.5">
        <div className="flex items-center gap-1">
          {limits.schedules.number}
          {limits.schedules.canExceed ? "+" : ""}{" "}
          <DefinitionTip
            title={pricingDefinitions.schedules.title}
            content={pricingDefinitions.schedules.content}
          >
            schedules
          </DefinitionTip>
        </div>
        {children && <span className="text-xs text-text-dimmed">{children}</span>}
      </div>
    </FeatureItem>
  );
}

function LogRetention({ limits }: { limits: Limits }) {
  return <FeatureItem checked>{limits.logRetentionDays.number} day log retention</FeatureItem>;
}

function SupportLevel({ limits }: { limits: Limits }) {
  return (
    <FeatureItem checked>
      {limits.support === "community" ? "Community support" : "Priority support"}
    </FeatureItem>
  );
}

function Alerts({ limits }: { limits: Limits }) {
  if (limits.alerts.number === 0) {
    return (
      <FeatureItem>
        <DefinitionTip
          title={pricingDefinitions.alerts.title}
          content={pricingDefinitions.alerts.content}
        >
          Alert destinations
        </DefinitionTip>
      </FeatureItem>
    );
  }

  return (
    <FeatureItem checked>
      {limits.alerts.number}
      {limits.alerts.canExceed ? "+" : ""}{" "}
      <DefinitionTip
        title={pricingDefinitions.alerts.title}
        content={pricingDefinitions.alerts.content}
      >
        alert destinations
      </DefinitionTip>
    </FeatureItem>
  );
}

function RealtimeConcurrency({ limits, children }: { limits: Limits; children?: React.ReactNode }) {
  return (
    <FeatureItem checked>
      <div className="flex flex-col gap-y-0.5">
        <div className="flex items-start gap-1">
          {limits.realtimeConcurrentConnections.canExceed ? (
            <>
              {limits.realtimeConcurrentConnections.number}
              {"+"}
            </>
          ) : (
            <>{limits.realtimeConcurrentConnections.number} </>
          )}{" "}
          <DefinitionTip
            title={pricingDefinitions.realtime.title}
            content={pricingDefinitions.realtime.content}
          >
            concurrent Realtime connections
          </DefinitionTip>
        </div>
        {children && <span className="text-xs text-text-dimmed">{children}</span>}
      </div>
    </FeatureItem>
  );
}

function MetricDashboards({ limits, children }: { limits: Limits; children?: React.ReactNode }) {
  if (limits.metricDashboards.number === 0) {
    return (
      <FeatureItem>
        <DefinitionTip
          title={pricingDefinitions.metricDashboards.title}
          content={pricingDefinitions.metricDashboards.content}
        >
          Custom dashboards
        </DefinitionTip>
      </FeatureItem>
    );
  }

  return (
    <FeatureItem checked>
      <div className="flex flex-col gap-y-0.5">
        <div className="flex items-center gap-1">
          {limits.metricDashboards.number}
          {limits.metricDashboards.canExceed ? "+" : ""}{" "}
          <DefinitionTip
            title={pricingDefinitions.metricDashboards.title}
            content={pricingDefinitions.metricDashboards.content}
          >
            custom {limits.metricDashboards.number === 1 ? "dashboard" : "dashboards"}
          </DefinitionTip>
        </div>
        {children && <span className="text-xs text-text-dimmed">{children}</span>}
      </div>
    </FeatureItem>
  );
}

function QueryPeriod({ limits }: { limits: Limits }) {
  return (
    <FeatureItem checked>
      {limits.queryPeriodDays.number} {limits.queryPeriodDays.number === 1 ? "day" : "days"}{" "}
      <DefinitionTip
        title={pricingDefinitions.queryPeriod.title}
        content={pricingDefinitions.queryPeriod.content}
      >
        query period
      </DefinitionTip>
    </FeatureItem>
  );
}

function HIPAAAddOn({
  children,
  checkedColor = "primary",
}: {
  children?: React.ReactNode;
  checkedColor?: "primary" | "bright";
}) {
  return (
    <FeatureItem checked checkedColor={checkedColor}>
      <div className="flex flex-col gap-y-0.5">
        <div>
          <DefinitionTip
            title={pricingDefinitions.hipaaBaa.title}
            content={pricingDefinitions.hipaaBaa.content}
          >
            HIPAA BAA
          </DefinitionTip>{" "}
          add-on
        </div>
        {children && <span className="text-xs text-text-dimmed">{children}</span>}
      </div>
    </FeatureItem>
  );
}

function Branches({ limits, children }: { limits: Limits; children?: React.ReactNode }) {
  return (
    <FeatureItem checked={limits.branches.number > 0}>
      <div className="flex flex-col gap-y-0.5">
        <div className="flex items-center gap-1">
          {limits.branches.number > 0 && (
            <>
              {limits.branches.number}
              {limits.branches.canExceed ? "+ " : " "}
            </>
          )}
          <DefinitionTip
            title={pricingDefinitions.branches.title}
            content={pricingDefinitions.branches.content}
          >
            {limits.branches.number > 0 ? "preview" : "Preview"} branches
          </DefinitionTip>
        </div>
        {children && <span className="text-xs text-text-dimmed">{children}</span>}
      </div>
    </FeatureItem>
  );
}
