/// <reference types="cypress" />
import { makeCompanyCategory } from "../../support/company-category-fixtures";
import {
  categoryMutationSuccessBody,
  companyCategoriesListUrl,
  companyCategoryCreateUrl,
  companyCategoryEditUrl,
} from "../../support/company-category-helpers";
import { stubCompanyCategoriesReads } from "../../support/company-category-intercepts";

describe("company categories create and edit forms", () => {
  beforeEach(() => {
    cy.setAuthCookies();
  });

  it("create: shows required error when name is empty", () => {
    stubCompanyCategoriesReads(() => []);
    cy.visit(companyCategoryCreateUrl());
    cy.getByCy("company-category-form").should("be.visible");
    cy.contains("h2", "Create Company Category").should("be.visible");
    cy.getByCy("admin-form-submit-button").click();
    cy.contains("This field is required").should("be.visible");
  });

  it("create: shows min length for one-character name", () => {
    stubCompanyCategoriesReads(() => []);
    cy.visit(companyCategoryCreateUrl());
    cy.getByCy("company-category-form-name-input").type("A");
    cy.getByCy("admin-form-submit-button").click();
    cy.contains("This field must be at least 2 characters long").should("be.visible");
  });

  it("create: shows min length when description is too short", () => {
    stubCompanyCategoriesReads(() => []);
    cy.visit(companyCategoryCreateUrl());
    cy.getByCy("company-category-form-name-input").type("Valid Name");
    cy.getByCy("company-category-form-description-input").type("short");
    cy.getByCy("admin-form-submit-button").click();
    cy.contains("This field must be at least 10 characters long").should("be.visible");
  });

  it("create: submits and redirects to list with success toast", () => {
    let categories: ReturnType<typeof makeCompanyCategory>[] = [];
    stubCompanyCategoriesReads(() => categories);

    cy.intercept("POST", "**/api/proxy/company-categories", (req) => {
      categories = [
        makeCompanyCategory(
          {
            id: "507f1f77bcf86cd799439099",
            name: "New Category",
            description: "A description with enough characters.",
          },
          99,
        ),
      ];
      req.reply({
        statusCode: 201,
        body: categoryMutationSuccessBody("Category created"),
      });
    }).as("createCategory");

    cy.visit(companyCategoryCreateUrl());
    cy.getByCy("company-category-form-name-input").type("New Category");
    cy.getByCy("company-category-form-description-input").type(
      "A description with enough characters.",
    );
    cy.getByCy("admin-form-submit-button").click();
    cy.wait("@createCategory");
    // Next.js navigation can be slightly delayed in CI/headless runs.
    cy.location("pathname", { timeout: 15000 }).should("eq", "/company-categories");
    cy.contains(/success|created|Category created/i).should("be.visible");
    cy.contains("New Category").should("be.visible");
  });

  it("create: disables submit while request is in flight", () => {
    stubCompanyCategoriesReads(() => []);
    cy.intercept("POST", "**/api/proxy/company-categories", (req) => {
      req.reply({
        delay: 1400,
        statusCode: 201,
        body: categoryMutationSuccessBody("Category created"),
      });
    }).as("slowCreate");

    cy.visit(companyCategoryCreateUrl());
    cy.getByCy("company-category-form-name-input").type("Slow Category");
    cy.getByCy("company-category-form-description-input").type(
      "Description long enough for validation rules here.",
    );
    cy.getByCy("admin-form-submit-button").click();
    cy.getByCy("admin-form-submit-button").should("be.disabled");
    cy.getByCy("admin-form-submit-button").find("div.animate-spin").should("exist");
    cy.wait("@slowCreate");
    cy.get("@slowCreate.all").should("have.length", 1);
  });

  it("edit: prefills fields and updates then returns to list", () => {
    const cat = makeCompanyCategory({ name: "Before Name", id: "507f1f77bcf86cd799439055" }, 5);
    let categories = [cat];

    stubCompanyCategoriesReads(() => categories);
    cy.intercept("PUT", `**/api/proxy/company-categories/${cat.id}`, (req) => {
      categories = [
        makeCompanyCategory(
          {
            ...cat,
            name: "After Name",
          },
          5,
        ),
      ];
      req.reply({
        statusCode: 200,
        body: categoryMutationSuccessBody("Category updated"),
      });
    }).as("updateCategory");

    cy.visit(companyCategoryEditUrl(cat.id));
    cy.contains("h2", "Edit Company Category").should("be.visible");
    cy.getByCy("company-category-form-name-input").should("have.value", "Before Name");
    cy.getByCy("company-category-form-name-input").clear().type("After Name");
    cy.getByCy("admin-form-submit-button").click();
    cy.wait("@updateCategory");
    cy.location("pathname").should("eq", "/company-categories");
    cy.contains(/success|updated|Category updated/i).should("be.visible");
    cy.contains("After Name").should("be.visible");
  });

  it("edit: cancel uses back navigation", () => {
    const cat = makeCompanyCategory({}, 1);
    stubCompanyCategoriesReads(() => [cat]);

    cy.visit(companyCategoriesListUrl());
    cy.getByCy(`company-categories-row-edit-${cat.id}`).click();
    cy.location("pathname").should("eq", `/company-categories/edit/${cat.id}`);
    cy.getByCy("admin-form-cancel-button").click();
    cy.location("pathname").should("eq", "/company-categories");
  });

  it("create: cancel navigates back when opened from list", () => {
    stubCompanyCategoriesReads(() => [makeCompanyCategory({}, 1)]);
    cy.visit(companyCategoriesListUrl());
    cy.getByCy("company-categories-create-button").click();
    cy.location("pathname").should("eq", "/company-categories/create");
    cy.getByCy("admin-form-cancel-button").click();
    cy.location("pathname").should("eq", "/company-categories");
  });
});
