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

describe("company categories list", () => {
  beforeEach(() => {
    cy.setAuthCookies();
  });

  it("toggles published optimistically, then keeps state after PATCH succeeds", () => {
    const cat = makeCompanyCategory({ published: false }, 1);
    let categories: ReturnType<typeof makeCompanyCategory>[] = [cat];

    stubCompanyCategoriesReads(() => categories);
    cy.intercept("PATCH", "**/api/proxy/company-categories/**/publish", (req) => {
      const m = req.url.match(/company-categories\/([^/]+)\/publish/);
      const id = m?.[1];
      if (id) {
        categories = categories.map((c) =>
          c.id === id ? { ...c, published: !c.published } : c,
        );
      }
      req.reply({
        statusCode: 200,
        body: { success: true, message: "Publish status updated", data: {} },
      });
    }).as("togglePublished");

    cy.visit(companyCategoriesListUrl());
    const toggle = () => cy.getByCy("company-categories-published-toggle-" + cat.id);
    toggle().should("not.be.checked");
    toggle().click({ force: true });
    // Optimistic update (useOptimistic) before the network call finishes.
    toggle().should("be.checked");
    cy.wait("@togglePublished");
    toggle().should("be.checked");
  });

  it("reverts published toggle when PATCH fails", () => {
    const cat = makeCompanyCategory({ published: false }, 1);
    stubCompanyCategoriesReads(() => [cat]);
    cy.intercept("PATCH", "**/api/proxy/company-categories/**/publish", {
      statusCode: 500,
      body: { success: false, message: "Server error" },
      delay: 200,
    }).as("togglePublishedFail");

    cy.visit(companyCategoriesListUrl());
    const toggle = () => cy.getByCy("company-categories-published-toggle-" + cat.id);
    toggle().should("not.be.checked");
    toggle().click({ force: true });
    toggle().should("be.checked");
    cy.wait("@togglePublishedFail");
    toggle().should("not.be.checked");
  });

  it("opens filter modal, searches by q, and updates the list", () => {
    const alpha = makeCompanyCategory({ name: "Alpha Row", id: "507f1f77bcf86cd799439011" }, 1);
    const beta = makeCompanyCategory({ name: "Beta Row", id: "507f1f77bcf86cd799439012" }, 2);
    let categories = [alpha, beta];

    stubCompanyCategoriesReads(() => categories);

    cy.visit(companyCategoriesListUrl());
    cy.contains("Alpha Row").should("be.visible");
    cy.getByCy("company-categories-filter-button").click();
    cy.getByCy("company-categories-filter-form").should("be.visible");
    cy.getByCy("company-categories-filter-search-input").clear().type("Beta");
    cy.then(() => { categories = [beta]; });
    cy.getByCy("company-categories-filter-submit-button").click();
    cy.location("search").should("include", "q=Beta");
    cy.contains("Beta Row").should("be.visible");
    cy.contains("Alpha Row").should("not.exist");
  });

  it("filters by published select and clears published filter", () => {
    const pub = makeCompanyCategory({ name: "Pub Cat", published: true }, 1);
    const draft = makeCompanyCategory(
      { name: "Draft Cat", published: false, id: "507f1f77bcf86cd799439013" },
      2,
    );
    let categories = [pub, draft];

    stubCompanyCategoriesReads(() => categories);

    cy.visit(companyCategoriesListUrl());
    cy.getByCy("company-categories-filter-button").click();
    cy.getByCy("company-categories-filter-published-select").select("false");
    cy.then(() => { categories = [draft]; });
    cy.getByCy("company-categories-filter-submit-button").click();
    cy.location("search").should("include", "published=false");
    cy.contains("Draft Cat").should("be.visible");
    cy.contains("Pub Cat").should("not.exist");

    cy.getByCy("company-categories-filter-button").click();
    cy.getByCy("company-categories-filter-published-select-clear").click();
    cy.then(() => { categories = [pub, draft]; });
    cy.getByCy("company-categories-filter-submit-button").click();
    cy.location("search").should("not.include", "published=false");
    cy.contains("Pub Cat").should("be.visible");
  });

  it("closes filter modal without applying", () => {
    const cat = makeCompanyCategory({}, 1);
    stubCompanyCategoriesReads(() => [cat]);

    cy.visit(companyCategoriesListUrl());
    cy.getByCy("company-categories-filter-button").click();
    cy.getByCy("company-categories-filter-form").should("be.visible");
    cy.getByCy("company-categories-filter-close-button").click();
    cy.getByCy("company-categories-filter-form").should("not.exist");
  });

  it("navigates to create from header button", () => {
    stubCompanyCategoriesReads(() => [makeCompanyCategory({}, 1)]);
    cy.visit(companyCategoriesListUrl());
    cy.getByCy("company-categories-create-button").click();
    cy.location("pathname").should("eq", "/company-categories/create");
    cy.getByCy("company-category-form").should("be.visible");
    cy.contains("h2", "Create Company Category").should("be.visible");
  });

  it("opens edit route for a row", () => {
    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.contains("h2", "Edit Company Category").should("be.visible");
  });

  it("deletes after confirm and shows empty state", () => {
    const cat = makeCompanyCategory({}, 1);
    let categories = [cat];

    stubCompanyCategoriesReads(() => categories);
    cy.intercept("DELETE", `**/api/proxy/company-categories/${cat.id}`, {
      statusCode: 200,
      body: { success: true, message: "Deleted", data: {} },
    }).as("deleteCategory");

    cy.visit(companyCategoriesListUrl());
    cy.getByCy(`company-categories-row-delete-${cat.id}`).click();
    cy.getByCy("confirmation-modal").should("be.visible");
    cy.getByCy("confirmation-modal-cancel").click();
    cy.getByCy("confirmation-modal").should("not.exist");

    cy.getByCy(`company-categories-row-delete-${cat.id}`).click();
    cy.then(() => { categories = []; });
    cy.getByCy("confirmation-modal-confirm").click();
    cy.wait("@deleteCategory");
    cy.getByCy("empty-list-message").should("contain.text", "No categories were found");
  });
});
