import { describe, expect, it } from "vitest";
import { parse } from "@conform-to/zod";
import { billingAlertsSchema } from "~/components/billing/BillingAlertsSection";
import {
  billingLimitFormSchema,
  getBillingLimitFormLastSubmission,
  isBillingLimitFormDirty,
} from "~/components/billing/BillingLimitConfigSection";
import { billingLimitRecoveryFormSchema } from "~/components/billing/BillingLimitRecoveryPanel";
import { isBillingLimitSettingsFormSubmission } from "~/routes/_app.orgs.$organizationSlug.settings.billing-limits/billingLimitsRevalidation";
import { getSuggestedRecoveryLimitDollars } from "~/components/billing/billingLimitFormat";
import {
  getAlertsResetRequested,
  getEffectiveLimitCentsAfterLimitSave,
  getResolveSubmitted,
  getSubmittedResumeMode,
  isEnforcementActive,
} from "~/routes/_app.orgs.$organizationSlug.settings.billing-limits/billingLimitsRoute.server";
import { loader as billingAlertsRedirectLoader } from "~/routes/_app.orgs.$organizationSlug.settings.billing-alerts/route";

function billingLimitsRequest(search = ""): Request {
  return new Request(`http://localhost:3030/orgs/acme/settings/billing-limits${search}`);
}

describe("billingLimitsRoute.server", () => {
  describe("isEnforcementActive", () => {
    it("returns true in grace", () => {
      expect(
        isEnforcementActive({
          isConfigured: true,
          mode: "plan",
          cancelInProgressRuns: false,
          limitState: { status: "grace", hitAt: "t", graceEndsAt: "t" },
          effectiveAmountCents: 5000,
          gracePeriodMs: 86_400_000,
        })
      ).toBe(true);
    });

    it("returns true when rejected", () => {
      expect(
        isEnforcementActive({
          isConfigured: true,
          mode: "custom",
          amountCents: 2500,
          cancelInProgressRuns: false,
          limitState: { status: "rejected", hitAt: "t", graceEndsAt: "t" },
          effectiveAmountCents: 2500,
          gracePeriodMs: 86_400_000,
        })
      ).toBe(true);
    });

    it("returns false when unconfigured", () => {
      expect(
        isEnforcementActive({
          isConfigured: false,
          gracePeriodMs: 86_400_000,
        })
      ).toBe(false);
    });

    it("returns false when configured and ok", () => {
      expect(
        isEnforcementActive({
          isConfigured: true,
          mode: "none",
          cancelInProgressRuns: false,
          limitState: { status: "ok" },
          effectiveAmountCents: null,
          gracePeriodMs: 86_400_000,
        })
      ).toBe(false);
    });
  });

  describe("getAlertsResetRequested", () => {
    it("returns true when alertsReset=1 is present", () => {
      expect(getAlertsResetRequested(billingLimitsRequest("?alertsReset=1"))).toBe(true);
    });

    it("returns false when the param is absent", () => {
      expect(getAlertsResetRequested(billingLimitsRequest())).toBe(false);
    });

    it("returns false for other param values", () => {
      expect(getAlertsResetRequested(billingLimitsRequest("?alertsReset=true"))).toBe(false);
    });
  });

  describe("getResolveSubmitted", () => {
    it("returns true when resolved=1 is present", () => {
      expect(getResolveSubmitted(billingLimitsRequest("?resolved=1"))).toBe(true);
    });

    it("returns false when the param is absent", () => {
      expect(getResolveSubmitted(billingLimitsRequest())).toBe(false);
    });
  });

  describe("getSubmittedResumeMode", () => {
    it("parses resumeMode from the query string", () => {
      expect(getSubmittedResumeMode(billingLimitsRequest("?resumeMode=new_only"))).toBe("new_only");
    });

    it("returns null for invalid values", () => {
      expect(getSubmittedResumeMode(billingLimitsRequest("?resumeMode=invalid"))).toBeNull();
    });
  });

  describe("getSuggestedRecoveryLimitDollars", () => {
    it("uses max(limit + $50, limit × 1.25, spend × 1.25) rounded up to $50", () => {
      expect(getSuggestedRecoveryLimitDollars(5_000, 4_500)).toBe(100);
      expect(getSuggestedRecoveryLimitDollars(50_000, 48_000)).toBe(650);
      expect(getSuggestedRecoveryLimitDollars(50_000, 60_000)).toBe(750);
      expect(getSuggestedRecoveryLimitDollars(1_000_000, 950_000)).toBe(12_500);
    });

    it("falls back to spend × 1.25 when there is no effective limit", () => {
      expect(getSuggestedRecoveryLimitDollars(null, 4_500)).toBe(100);
    });
  });

  describe("isBillingLimitSettingsFormSubmission", () => {
    it("returns true for billing-limit POST", () => {
      const formData = new FormData();
      formData.set("intent", "billing-limit");
      expect(isBillingLimitSettingsFormSubmission("post", formData)).toBe(true);
    });

    it("returns true for billing-alerts POST", () => {
      const formData = new FormData();
      formData.set("intent", "billing-alerts");
      expect(isBillingLimitSettingsFormSubmission("POST", formData)).toBe(true);
    });

    it("returns true for billing-limit-resolve POST", () => {
      const formData = new FormData();
      formData.set("intent", "billing-limit-resolve");
      expect(isBillingLimitSettingsFormSubmission("post", formData)).toBe(true);
    });

    it("returns false for unrelated POST", () => {
      const formData = new FormData();
      formData.set("intent", "other");
      expect(isBillingLimitSettingsFormSubmission("post", formData)).toBe(false);
    });

    it("returns false without form data", () => {
      expect(isBillingLimitSettingsFormSubmission("post", undefined)).toBe(false);
    });
  });

  describe("getEffectiveLimitCentsAfterLimitSave", () => {
    it("uses custom amount in cents for custom mode", () => {
      expect(getEffectiveLimitCentsAfterLimitSave("custom", 5000, 42.5)).toBe(4250);
    });

    it("uses plan limit cents for plan mode", () => {
      expect(getEffectiveLimitCentsAfterLimitSave("plan", 5000)).toBe(5000);
    });

    it("uses plan limit cents for none mode", () => {
      expect(getEffectiveLimitCentsAfterLimitSave("none", 5000)).toBe(5000);
    });
  });
});

describe("billing-alerts redirect route", () => {
  it("redirects to billing-limits", async () => {
    const response = await billingAlertsRedirectLoader({
      params: { organizationSlug: "acme" },
      request: new Request("http://localhost:3030/orgs/acme/settings/billing-alerts"),
      context: {},
    });

    expect(response.status).toBe(302);
    expect(response.headers.get("Location")).toBe("/orgs/acme/settings/billing-limits");
  });
});

describe("billing-limits form validation", () => {
  it("rejects duplicate alert thresholds", () => {
    const formData = new FormData();
    formData.set("intent", "billing-alerts");
    formData.append("emails", "a@example.com");
    formData.append("alertLevels", "75");
    formData.append("alertLevels", "75");

    const submission = parse(formData, { schema: billingAlertsSchema });
    expect(submission.error?.alertLevels).toBeTruthy();
  });

  it("rejects non-numeric alert thresholds", () => {
    const formData = new FormData();
    formData.set("intent", "billing-alerts");
    formData.append("emails", "a@example.com");
    formData.append("alertLevels", "75");
    formData.append("alertLevels", "not-a-number");

    const submission = parse(formData, { schema: billingAlertsSchema });
    expect(submission.error?.["alertLevels[1]"]).toBeTruthy();
  });

  it("accepts a valid billing limit custom submission", () => {
    const formData = new FormData();
    formData.set("intent", "billing-limit");
    formData.set("mode", "custom");
    formData.set("amount", "100");
    formData.set("cancelInProgressRuns", "on");

    const submission = parse(formData, { schema: billingLimitFormSchema });
    expect(submission.value).toEqual({
      mode: "custom",
      amount: 100,
      cancelInProgressRuns: true,
    });
  });

  it("parses none mode with cancelInProgressRuns from the form", () => {
    const formData = new FormData();
    formData.set("mode", "none");
    formData.set("cancelInProgressRuns", "on");

    const submission = parse(formData, { schema: billingLimitFormSchema });
    expect(submission.value?.mode).toBe("none");
    expect(submission.value?.cancelInProgressRuns).toBe(true);
  });

  it("accepts a valid billing limit resolve submission", () => {
    const formData = new FormData();
    formData.set("intent", "billing-limit-resolve");
    formData.set("action", "increase");
    formData.set("newAmount", "1500");
    formData.set("resumeMode", "queue");

    const submission = parse(formData, { schema: billingLimitRecoveryFormSchema });
    expect(submission.value).toEqual({
      action: "increase",
      newAmount: 1500,
      resumeMode: "queue",
    });
  });

  it("accepts remove resolve with new_only resume mode", () => {
    const formData = new FormData();
    formData.set("action", "remove");
    formData.set("resumeMode", "new_only");

    const submission = parse(formData, { schema: billingLimitRecoveryFormSchema });
    expect(submission.value).toEqual({
      action: "remove",
      resumeMode: "new_only",
    });
  });
});

describe("isBillingLimitFormDirty", () => {
  const unconfiguredLimit = { isConfigured: false as const, gracePeriodMs: 86_400_000 };
  const configuredPlanLimit = {
    isConfigured: true as const,
    mode: "plan" as const,
    cancelInProgressRuns: false,
    limitState: { status: "ok" as const },
    effectiveAmountCents: 5000,
    gracePeriodMs: 86_400_000,
  };

  it("is dirty when billing limit has never been saved", () => {
    expect(
      isBillingLimitFormDirty({
        billingLimit: unconfiguredLimit,
        mode: "none",
        customAmount: "",
        cancelInProgressRuns: false,
      })
    ).toBe(true);
  });

  it("is clean when configured values match saved state", () => {
    expect(
      isBillingLimitFormDirty({
        billingLimit: configuredPlanLimit,
        mode: "plan",
        customAmount: "",
        cancelInProgressRuns: false,
      })
    ).toBe(false);
  });

  it("is dirty when configured mode changes", () => {
    expect(
      isBillingLimitFormDirty({
        billingLimit: configuredPlanLimit,
        mode: "none",
        customAmount: "",
        cancelInProgressRuns: false,
      })
    ).toBe(true);
  });
});

describe("getBillingLimitFormLastSubmission", () => {
  it("drops amount errors when the selected mode is not custom", () => {
    const submission = parse(
      (() => {
        const formData = new FormData();
        formData.set("mode", "custom");
        formData.set("amount", "0");
        return formData;
      })(),
      { schema: billingLimitFormSchema }
    );

    expect(
      getBillingLimitFormLastSubmission(submission, "plan", true)?.error?.amount
    ).toBeUndefined();
  });

  it("keeps amount errors while custom mode is selected", () => {
    const submission = parse(
      (() => {
        const formData = new FormData();
        formData.set("mode", "custom");
        formData.set("amount", "0");
        return formData;
      })(),
      { schema: billingLimitFormSchema }
    );

    expect(
      getBillingLimitFormLastSubmission(submission, "custom", true)?.error?.amount
    ).toBeTruthy();
  });

  it("returns undefined when the form is clean", () => {
    const submission = parse(
      (() => {
        const formData = new FormData();
        formData.set("mode", "custom");
        formData.set("amount", "0");
        return formData;
      })(),
      { schema: billingLimitFormSchema }
    );

    expect(getBillingLimitFormLastSubmission(submission, "custom", false)).toBeUndefined();
  });
});
