import { importShared } from './__federation_fn_import-TbMgVVsT.js';
import { g as get, s as set, c as appendErrors, d as useFieldArray$1, a as useForm, j as jsxRuntimeExports, e as useWatch } from './index.esm-DB88n2Vs.js';
import { l as parse, m as parseAsync, K as $ZodError } from './registries-Tz_dluz3.js';
import { b as billingPlanEntityType, c as createStripePluginDefinitionSchema, a as createBillingPartialDefinition } from './plugin-definition-DC7rEk-r.js';
import { n as MdEdit, o as MdDeleteOutline, p as MdAdd } from './index-CSsAFslH.js';

const r=(t,r,o)=>{if(t&&"reportValidity"in t){const s=get(o,r);t.setCustomValidity(s&&s.message||""),t.reportValidity();}},o=(e,t)=>{for(const o in t.fields){const s=t.fields[o];s&&s.ref&&"reportValidity"in s.ref?r(s.ref,o,e):s&&s.refs&&s.refs.forEach(t=>r(t,o,e));}},s$1=(r,s)=>{s.shouldUseNativeValidation&&o(r,s);const n={};for(const o in r){const f=get(s.fields,o),c=Object.assign(r[o]||{},{ref:f&&f.ref});if(i$1(s.names||Object.keys(r),o)){const r=Object.assign({},get(n,o));set(r,"root",c),set(n,o,r);}else set(n,o,c);}return n},i$1=(e,t)=>{const r=n(t);return e.some(e=>n(e).match(`^${r}\\.\\d+`))};function n(e){return e.replace(/\]|\[/g,"")}

function t(r,e){try{var o=r();}catch(r){return e(r)}return o&&o.then?o.then(void 0,e):o}function s(r,e){for(var n={};r.length;){var t=r[0],s=t.code,i=t.message,a=t.path.join(".");if(!n[a])if("unionErrors"in t){var u=t.unionErrors[0].errors[0];n[a]={message:u.message,type:u.code};}else n[a]={message:i,type:s};if("unionErrors"in t&&t.unionErrors.forEach(function(e){return e.errors.forEach(function(e){return r.push(e)})}),e){var c=n[a].types,f=c&&c[t.code];n[a]=appendErrors(a,e,n,s,f?[].concat(f,t.message):t.message);}r.shift();}return n}function i(r,e){for(var n={};r.length;){var t=r[0],s=t.code,i=t.message,a=t.path.join(".");if(!n[a])if("invalid_union"===t.code&&t.errors.length>0){var u=t.errors[0][0];n[a]={message:u.message,type:u.code};}else n[a]={message:i,type:s};if("invalid_union"===t.code&&t.errors.forEach(function(e){return e.forEach(function(e){return r.push(e)})}),e){var c=n[a].types,f=c&&c[t.code];n[a]=appendErrors(a,e,n,s,f?[].concat(f,t.message):t.message);}r.shift();}return n}function a(o$1,a,u){if(void 0===u&&(u={}),function(r){return "_def"in r&&"object"==typeof r._def&&"typeName"in r._def}(o$1))return function(n,i,c){try{return Promise.resolve(t(function(){return Promise.resolve(o$1["sync"===u.mode?"parse":"parseAsync"](n,a)).then(function(e){return c.shouldUseNativeValidation&&o({},c),{errors:{},values:u.raw?Object.assign({},n):e}})},function(r){if(function(r){return Array.isArray(null==r?void 0:r.issues)}(r))return {values:{},errors:s$1(s(r.errors,!c.shouldUseNativeValidation&&"all"===c.criteriaMode),c)};throw r}))}catch(r){return Promise.reject(r)}};if(function(r){return "_zod"in r&&"object"==typeof r._zod}(o$1))return function(s,c,f){try{return Promise.resolve(t(function(){return Promise.resolve(("sync"===u.mode?parse:parseAsync)(o$1,s,a)).then(function(e){return f.shouldUseNativeValidation&&o({},f),{errors:{},values:u.raw?Object.assign({},s):e}})},function(r){if(function(r){return r instanceof $ZodError}(r))return {values:{},errors:s$1(i(r.issues,!f.shouldUseNativeValidation&&"all"===f.criteriaMode),f)};throw r}))}catch(r){return Promise.reject(r)}};throw new Error("Invalid input: not a Zod schema")}

// src/rhf/useFieldArray.ts
const {useMemo: useMemo$2} = await importShared('react');
function useFieldArray(props) {
  const original = useFieldArray$1(props);
  const newFields = useMemo$2(() => {
    if (!props.getTransformer) {
      return original.fields;
    }
    return original.fields.map(props.getTransformer);
  }, [original.fields, props.getTransformer]);
  return {
    fields: newFields,
    move: original.move,
    remove: original.remove,
    swap: original.swap,
    prepend: (value, options) => {
      if (!props.setTransformer) {
        return original.prepend(value, options);
      }
      const newValue = Array.isArray(value) ? value.map(props.setTransformer) : props.setTransformer(value);
      original.prepend(newValue, options);
    },
    append: (value, options) => {
      if (!props.setTransformer) {
        return original.append(value, options);
      }
      const newValue = Array.isArray(value) ? value.map(props.setTransformer) : props.setTransformer(value);
      original.append(newValue, options);
    },
    insert: (index, value, options) => {
      if (!props.setTransformer) {
        return original.insert(index, value, options);
      }
      const newValue = Array.isArray(value) ? value.map(props.setTransformer) : props.setTransformer(value);
      original.insert(index, newValue, options);
    },
    update: (index, value) => {
      if (!props.setTransformer) {
        return original.update(index, value);
      }
      const newValue = props.setTransformer(value);
      original.update(index, newValue);
    },
    replace: (value) => {
      if (!props.setTransformer) {
        return original.replace(value);
      }
      const newValue = props.setTransformer(value);
      original.replace(newValue);
    }
  };
}

const {authConfigSpec} = await importShared('@baseplate-dev/project-builder-lib');

const {useProjectDefinition: useProjectDefinition$2} = await importShared('@baseplate-dev/project-builder-lib/web');

const {Button: Button$1,Dialog,DialogContent,DialogDescription,DialogFooter,DialogHeader,DialogTitle,InputFieldController,MultiComboboxFieldController} = await importShared('@baseplate-dev/ui-components');
const {useId,useMemo: useMemo$1} = await importShared('react');
const {z} = await importShared('zod');
const planFormSchema = z.object({
  id: z.string(),
  key: z.string().min(1, "Plan key is required").regex(/^[a-z0-9-]+$/, "Must be kebab-case (e.g. pro-plan)"),
  displayName: z.string().min(1, "Display name is required"),
  grantedRoles: z.array(z.string()).default([])
});
function PlanDialog({
  open,
  onOpenChange,
  plan,
  isNew = false,
  onSave
}) {
  const { definition, definitionContainer } = useProjectDefinition$2();
  const authConfig = definitionContainer.pluginStore.use(authConfigSpec);
  const availableRoles = useMemo$1(() => {
    const config = authConfig.getAuthConfig(definition);
    return (config?.roles ?? []).filter((r) => !r.builtIn).map((r) => ({
      id: r.id,
      name: r.name,
      comment: r.comment
    }));
  }, [authConfig, definition]);
  const authPluginUrl = authConfig.pluginKey ? `/plugins/edit/${authConfig.pluginKey}` : void 0;
  const form = useForm({
    resolver: a(planFormSchema),
    values: plan
  });
  const { control, handleSubmit } = form;
  const onSubmit = handleSubmit((data) => {
    onSave(data);
    onOpenChange?.(false);
  });
  const formId = useId();
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntimeExports.jsx(DialogContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
    "form",
    {
      id: formId,
      onSubmit: (e) => {
        e.stopPropagation();
        return onSubmit(e);
      },
      children: [
        /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogHeader, { children: [
          /* @__PURE__ */ jsxRuntimeExports.jsx(DialogTitle, { children: isNew ? "Add Plan" : "Edit Plan" }),
          /* @__PURE__ */ jsxRuntimeExports.jsx(DialogDescription, { children: isNew ? "Enter the details for the new billing plan." : "Update the plan details below." })
        ] }),
        /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "payments:space-y-4 payments:py-4", children: [
          /* @__PURE__ */ jsxRuntimeExports.jsx(
            InputFieldController,
            {
              label: "Plan Key",
              name: "key",
              control,
              placeholder: "e.g. pro-plan",
              description: "Kebab-case identifier used in code and Stripe metadata"
            }
          ),
          /* @__PURE__ */ jsxRuntimeExports.jsx(
            InputFieldController,
            {
              label: "Display Name",
              name: "displayName",
              control,
              placeholder: "e.g. Pro Plan"
            }
          ),
          /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
            /* @__PURE__ */ jsxRuntimeExports.jsx(
              MultiComboboxFieldController,
              {
                label: "Granted Roles",
                name: "grantedRoles",
                control,
                options: availableRoles,
                getOptionLabel: (role) => role.name,
                getOptionValue: (role) => role.id,
                placeholder: "Select roles...",
                description: "Auth roles granted when this plan is active"
              }
            ),
            authPluginUrl ? /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "payments:mt-1 payments:text-xs payments:text-muted-foreground", children: [
              "Manage roles in the",
              " ",
              /* @__PURE__ */ jsxRuntimeExports.jsx(
                "a",
                {
                  href: authPluginUrl,
                  className: "payments:underline payments:hover:text-foreground",
                  children: "Auth plugin settings"
                }
              ),
              "."
            ] }) : null
          ] })
        ] }),
        /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogFooter, { children: [
          /* @__PURE__ */ jsxRuntimeExports.jsx(
            Button$1,
            {
              type: "button",
              variant: "outline",
              onClick: () => {
                onOpenChange?.(false);
              },
              children: "Cancel"
            }
          ),
          /* @__PURE__ */ jsxRuntimeExports.jsxs(Button$1, { form: formId, type: "submit", children: [
            isNew ? "Add" : "Update",
            " Plan"
          ] })
        ] })
      ]
    }
  ) }) });
}

const {useProjectDefinition: useProjectDefinition$1} = await importShared('@baseplate-dev/project-builder-lib/web');

const {Button,RecordView,RecordViewActions,RecordViewItem,RecordViewItemList,SectionListSection: SectionListSection$1,SectionListSectionContent: SectionListSectionContent$1,SectionListSectionDescription: SectionListSectionDescription$1,SectionListSectionHeader: SectionListSectionHeader$1,SectionListSectionTitle: SectionListSectionTitle$1,useConfirmDialog} = await importShared('@baseplate-dev/ui-components');
const {useState} = await importShared('react');
function PlanEditorForm({ control }) {
  const { requestConfirm } = useConfirmDialog();
  const { append, update, remove } = useFieldArray({
    control,
    name: "billing.plans"
  });
  const { definitionContainer } = useProjectDefinition$1();
  const [planToEdit, setPlanToEdit] = useState();
  const [isEditing, setIsEditing] = useState(false);
  const watchedPlans = useWatch({ control, name: "billing.plans" });
  const plans = watchedPlans ?? [];
  function handleSavePlan(newPlan) {
    const existingIndex = plans.findIndex((p) => p.id === newPlan.id);
    if (existingIndex === -1) {
      append(newPlan);
    } else {
      update(existingIndex, newPlan);
    }
  }
  function handleDeletePlan(planIdx) {
    const plan = plans[planIdx];
    requestConfirm({
      title: "Delete Plan",
      content: `Are you sure you want to delete the plan "${plan.displayName}"?`,
      onConfirm: () => {
        remove(planIdx);
      }
    });
  }
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionListSection$1, { children: [
    /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionListSectionHeader$1, { children: [
      /* @__PURE__ */ jsxRuntimeExports.jsx(SectionListSectionTitle$1, { children: "Subscription Plans" }),
      /* @__PURE__ */ jsxRuntimeExports.jsx(SectionListSectionDescription$1, { children: "Define the subscription plans available to your users. Each plan generates a config entry with placeholder Stripe Price IDs that you replace with your actual IDs." })
    ] }),
    /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionListSectionContent$1, { className: "payments:space-y-4", children: [
      plans.map((plan, planIdx) => /* @__PURE__ */ jsxRuntimeExports.jsxs(RecordView, { children: [
        /* @__PURE__ */ jsxRuntimeExports.jsxs(RecordViewItemList, { children: [
          /* @__PURE__ */ jsxRuntimeExports.jsx(RecordViewItem, { title: "Key", children: plan.key }),
          /* @__PURE__ */ jsxRuntimeExports.jsx(RecordViewItem, { title: "Display Name", children: plan.displayName }),
          /* @__PURE__ */ jsxRuntimeExports.jsx(RecordViewItem, { title: "Granted Roles", children: plan.grantedRoles.length > 0 ? plan.grantedRoles.map((role) => definitionContainer.nameFromId(role)).join(", ") : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "payments:text-muted-foreground", children: "None" }) })
        ] }),
        /* @__PURE__ */ jsxRuntimeExports.jsxs(RecordViewActions, { children: [
          /* @__PURE__ */ jsxRuntimeExports.jsx(
            Button,
            {
              variant: "ghost",
              size: "icon",
              title: "Edit",
              "aria-label": "Edit plan",
              onClick: () => {
                setPlanToEdit(plan);
                setIsEditing(true);
              },
              children: /* @__PURE__ */ jsxRuntimeExports.jsx(MdEdit, {})
            }
          ),
          /* @__PURE__ */ jsxRuntimeExports.jsx(
            Button,
            {
              variant: "ghostDestructive",
              size: "icon",
              title: "Delete",
              "aria-label": "Delete plan",
              onClick: () => {
                handleDeletePlan(planIdx);
              },
              children: /* @__PURE__ */ jsxRuntimeExports.jsx(MdDeleteOutline, {})
            }
          )
        ] })
      ] }, plan.id)),
      /* @__PURE__ */ jsxRuntimeExports.jsx(
        PlanDialog,
        {
          open: isEditing,
          onOpenChange: setIsEditing,
          plan: planToEdit,
          isNew: planToEdit ? !plans.some((p) => p.id === planToEdit.id) : true,
          onSave: handleSavePlan
        }
      ),
      /* @__PURE__ */ jsxRuntimeExports.jsxs(
        Button,
        {
          variant: "secondary",
          size: "sm",
          onClick: () => {
            setPlanToEdit({
              id: billingPlanEntityType.generateNewId(),
              key: "",
              displayName: "",
              grantedRoles: []
            });
            setIsEditing(true);
          },
          children: [
            /* @__PURE__ */ jsxRuntimeExports.jsx(MdAdd, {}),
            "Add Plan"
          ]
        }
      )
    ] })
  ] });
}

const {applyMergedDefinition,authModelsSpec,diffDefinition,FeatureUtils,PluginUtils} = await importShared('@baseplate-dev/project-builder-lib');

const {DefinitionDiffAlert,FeatureComboboxFieldController,useBlockUnsavedChangesNavigate,useDefinitionSchema,useProjectDefinition,useResettableForm} = await importShared('@baseplate-dev/project-builder-lib/web');

const {FormActionBar,SectionList,SectionListSection,SectionListSectionContent,SectionListSectionDescription,SectionListSectionHeader,SectionListSectionTitle,SwitchFieldController} = await importShared('@baseplate-dev/ui-components');
const {useMemo} = await importShared('react');
function StripeDefinitionEditor({
  definition: pluginMetadata,
  metadata,
  onSave
}) {
  const { definition, definitionContainer, saveDefinitionWithFeedback } = useProjectDefinition();
  const stripePluginDefinitionSchema = useDefinitionSchema(
    createStripePluginDefinitionSchema
  );
  const defaultValues = useMemo(() => {
    if (pluginMetadata?.config) {
      return pluginMetadata.config;
    }
    return {
      stripeOptions: {},
      billing: {
        enabled: false,
        featureRef: FeatureUtils.getFeatureIdByNameOrDefault(
          definition,
          "billing"
        ),
        plans: []
      }
    };
  }, [definition, pluginMetadata?.config]);
  const form = useResettableForm({
    resolver: a(stripePluginDefinitionSchema),
    defaultValues
  });
  const { control, reset, handleSubmit } = form;
  const billingEnabled = useWatch({ control, name: "billing.enabled" });
  const billingFeatureRef = useWatch({
    control,
    name: "billing.featureRef"
  });
  const authModels = definitionContainer.pluginStore.use(authModelsSpec);
  const userModelName = authModels.getAuthModelsOrThrow(definition).user;
  const billingFeatureName = FeatureUtils.resolveFeatureName(
    definition,
    billingFeatureRef
  );
  const partialDef = useMemo(
    () => billingFeatureName ? createBillingPartialDefinition(billingFeatureName, userModelName) : { enums: [], models: [] },
    [billingFeatureName, userModelName]
  );
  const diff = useMemo(
    () => diffDefinition(
      definitionContainer.schema,
      definitionContainer.definition,
      partialDef
    ),
    [definitionContainer, partialDef]
  );
  const onSubmit = handleSubmit(
    (data) => saveDefinitionWithFeedback(
      (draftConfig) => {
        const billingData = { ...data };
        if (billingData.billing.enabled && billingData.billing.featureRef) {
          const featureName = FeatureUtils.resolveFeatureName(
            draftConfig,
            billingData.billing.featureRef
          );
          const updatedPartialDef = createBillingPartialDefinition(
            featureName,
            userModelName
          );
          applyMergedDefinition(
            definitionContainer,
            updatedPartialDef
          )(draftConfig);
          billingData.billing.featureRef = FeatureUtils.getFeatureIdByNameOrThrow(draftConfig, featureName);
        } else {
          billingData.billing = {
            enabled: false,
            plans: []
          };
        }
        PluginUtils.setPluginConfig(
          draftConfig,
          metadata,
          billingData,
          definitionContainer
        );
      },
      {
        successMessage: pluginMetadata ? "Successfully saved Stripe configuration!" : "Successfully enabled Stripe plugin!",
        onSuccess: () => {
          onSave();
        }
      }
    )
  );
  useBlockUnsavedChangesNavigate({ control, reset, onSubmit });
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "payments:relative payments:flex payments:h-full payments:flex-1 payments:flex-col payments:gap-4 payments:overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
    "div",
    {
      className: "payments:mb-[--action-bar-height] payments:flex payments:flex-1 payments:overflow-y-auto",
      style: {
        "--action-bar-height": "52px"
      },
      children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
        "form",
        {
          onSubmit,
          className: "payments:max-w-6xl payments:flex-1",
          children: [
            /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "payments:pb-16", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionList, { children: [
              /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionListSection, { children: [
                /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionListSectionHeader, { children: [
                  /* @__PURE__ */ jsxRuntimeExports.jsx(SectionListSectionTitle, { children: "Stripe Configuration" }),
                  /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionListSectionDescription, { children: [
                    "Stripe provides payment processing and webhook handling for your backend application. Configure the",
                    " ",
                    /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: "STRIPE_SECRET_KEY" }),
                    " environment variable in your project to activate Stripe integration."
                  ] })
                ] }),
                /* @__PURE__ */ jsxRuntimeExports.jsx(SectionListSectionContent, { className: "payments:space-y-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
                  SwitchFieldController,
                  {
                    label: "Enable Billing",
                    name: "billing.enabled",
                    control,
                    description: "When enabled, generates billing models, webhook handler, and subscription management code."
                  }
                ) })
              ] }),
              billingEnabled && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
                /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionListSection, { children: [
                  /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionListSectionHeader, { children: [
                    /* @__PURE__ */ jsxRuntimeExports.jsx(SectionListSectionTitle, { children: "Billing Configuration" }),
                    /* @__PURE__ */ jsxRuntimeExports.jsx(SectionListSectionDescription, { children: "Configure the feature path and review the models that will be created for billing." })
                  ] }),
                  /* @__PURE__ */ jsxRuntimeExports.jsxs(SectionListSectionContent, { className: "payments:space-y-6", children: [
                    /* @__PURE__ */ jsxRuntimeExports.jsx(
                      DefinitionDiffAlert,
                      {
                        diff,
                        upToDateMessage: "All required billing models are already configured correctly."
                      }
                    ),
                    /* @__PURE__ */ jsxRuntimeExports.jsx(
                      FeatureComboboxFieldController,
                      {
                        label: "Billing Feature Path",
                        name: "billing.featureRef",
                        control,
                        canCreate: true,
                        description: "Feature path where billing module code will be generated"
                      }
                    )
                  ] })
                ] }),
                /* @__PURE__ */ jsxRuntimeExports.jsx(PlanEditorForm, { control })
              ] })
            ] }) }),
            /* @__PURE__ */ jsxRuntimeExports.jsx(
              FormActionBar,
              {
                form,
                allowSaveWithoutDirty: !pluginMetadata || diff.hasChanges
              }
            )
          ]
        }
      )
    }
  ) });
}

const {createPluginModule,webConfigSpec} = await importShared('@baseplate-dev/project-builder-lib');
const web = createPluginModule({
  name: "web",
  dependencies: {
    webConfig: webConfigSpec
  },
  initialize: ({ webConfig }, { pluginKey }) => {
    webConfig.components.set(pluginKey, StripeDefinitionEditor);
  }
});

export { web as default };
//# sourceMappingURL=__federation_expose_stripeCoreWeb-D52NXeQS.js.map
