/**
 * Live Tracking — PibiSection (flat TanStack Table redesign)
 *
 * Tests the approver flow for the per-measure PIBI request log rendered
 * directly on the DealPage (pibi-surveys tab), not in a drawer.
 *
 *  1. Empty state renders with a "Log first PIBI" prompt
 *  2. Flat table shows existing rows (no batch grouping)
 *  3. Every row has always-editable cells (measure select, date inputs)
 *  4. Save button is disabled when row is clean, enabled after editing
 *  5. Save calls PATCH for existing rows
 *  6. Delete calls DELETE
 *  7. "+ Add row" appends a blank row; save calls POST
 *  8. "Mark all complete" PATCHes all incomplete rows
 *  9. Scope badges appear for approved / proposed measures
 *
 * Requires LIVE_PORTFOLIO_SLUG; skipped otherwise.
 * All network calls are intercepted — no real DB / HubSpot round-trips.
 */

const PORTFOLIO_SLUG = Cypress.env("LIVE_PORTFOLIO_SLUG");
const PORTFOLIO_ID_GLOB = "*";

function stubGet(pibiRequests = []) {
  cy.intercept(
    "GET",
    `/api/portfolio/${PORTFOLIO_ID_GLOB}/pibi-requests*`,
    { body: { pibiRequests } },
  ).as("getPibiRequests");
}

function stubMeasures(
  approvedMeasures = ["ASHP", "CWI"],
  instructedMeasures = [],
) {
  cy.intercept(
    "GET",
    `/api/portfolio/${PORTFOLIO_ID_GLOB}/pibi-measures*`,
    { body: { pibiMeasures: approvedMeasures, approvedMeasures, instructedMeasures } },
  ).as("getPibiMeasures");
}

function stubPost(response = { ok: true, insertedCount: 1, hubspotSync: "ok" }) {
  cy.intercept(
    "POST",
    `/api/portfolio/${PORTFOLIO_ID_GLOB}/pibi-requests`,
    { body: response },
  ).as("postPibiRequest");
}

function stubPatch(id, response = { ok: true, hubspotSync: "ok" }) {
  cy.intercept(
    "PATCH",
    `/api/portfolio/${PORTFOLIO_ID_GLOB}/pibi-requests/${id}`,
    { body: response },
  ).as(`patchPibiRequest-${id}`);
}

function stubDelete(id, response = { ok: true, hubspotSync: "ok" }) {
  cy.intercept(
    "DELETE",
    `/api/portfolio/${PORTFOLIO_ID_GLOB}/pibi-requests/${id}*`,
    { body: response },
  ).as(`deletePibiRequest-${id}`);
}

function openDealPageAtPibiTab() {
  cy.visit(`/portfolio/${PORTFOLIO_SLUG}/your-projects/live`);
  cy.contains("button, [role=tab]", "Properties").click();
  cy.get("[data-testid=property-row-link]").first().click();
  cy.get("[data-testid=deal-page-tab-pibi-surveys]").click();
}

describe("PibiSection", function () {
  before(function () {
    if (!PORTFOLIO_SLUG) {
      cy.log("LIVE_PORTFOLIO_SLUG not set — skipping PibiSection specs");
      this.skip();
    }
  });

  beforeEach(() => {
    stubMeasures();
  });

  // ── Cycle 1: Empty state ──────────────────────────────────────────────────

  it("shows empty state with Log first PIBI prompt when no requests exist", () => {
    stubGet([]);
    openDealPageAtPibiTab();
    cy.wait("@getPibiRequests");
    cy.get("[data-testid=pibi-empty-state]").should("be.visible");
    cy.get("[data-testid=pibi-empty-state]").should(
      "contain.text",
      "No PIBIs logged yet",
    );
    cy.get("[data-testid=pibi-empty-add-row]").should("be.visible");
  });

  // ── Cycle 2: Flat table renders rows (no batch groups) ────────────────────

  it("renders a flat table of rows with no batch grouping", () => {
    stubGet([
      {
        id: "1",
        measureName: "ASHP",
        orderedAt: "2026-05-01T00:00:00.000Z",
        completedAt: null,
      },
      {
        id: "2",
        measureName: "CWI",
        orderedAt: "2026-04-01T00:00:00.000Z",
        completedAt: null,
      },
    ]);
    openDealPageAtPibiTab();
    cy.wait("@getPibiRequests");

    cy.get("[data-testid=pibi-row-1]").should("be.visible");
    cy.get("[data-testid=pibi-row-2]").should("be.visible");
    cy.get("[data-testid=pibi-batch-group]").should("not.exist");
  });

  // ── Cycle 3: Always-editable cells ────────────────────────────────────────

  it("renders measure select and date inputs as always-editable cells", () => {
    stubGet([
      {
        id: "5",
        measureName: "ASHP",
        orderedAt: "2026-05-01T00:00:00.000Z",
        completedAt: null,
      },
    ]);
    openDealPageAtPibiTab();
    cy.wait("@getPibiRequests");

    cy.get("[data-testid=pibi-measure-select-5]").should("be.visible");
    cy.get("[data-testid=pibi-ordered-date-5]").should("be.visible");
    cy.get("[data-testid=pibi-completed-date-5]").should("be.visible");
  });

  // ── Cycle 4: Save disabled when clean, enabled after editing ──────────────

  it("shows Save disabled on load, enabled after editing a cell", () => {
    stubGet([
      {
        id: "6",
        measureName: "ASHP",
        orderedAt: "2026-05-01T00:00:00.000Z",
        completedAt: null,
      },
    ]);
    openDealPageAtPibiTab();
    cy.wait("@getPibiRequests");

    cy.get("[data-testid=pibi-save-6]").should("be.disabled");
    cy.get("[data-testid=pibi-ordered-date-6]").clear().type("2026-06-01");
    cy.get("[data-testid=pibi-save-6]").should("not.be.disabled");
  });

  // ── Cycle 5: Save calls PATCH ─────────────────────────────────────────────

  it("calls PATCH with updated fields when approver clicks Save", () => {
    stubGet([
      {
        id: "10",
        measureName: "ASHP",
        orderedAt: "2026-05-01T00:00:00.000Z",
        completedAt: null,
      },
    ]);
    stubPatch("10");
    openDealPageAtPibiTab();
    cy.wait("@getPibiRequests");

    cy.get("[data-testid=pibi-completed-date-10]").type("2026-05-15");
    cy.get("[data-testid=pibi-save-10]").click();

    cy.wait("@patchPibiRequest-10").then((interception) => {
      expect(interception.request.body.dealId).to.be.a("string");
      expect(interception.request.body.completedAt).to.include("2026-05-15");
    });
  });

  // ── Cycle 6: Delete calls DELETE ──────────────────────────────────────────

  it("calls DELETE when approver clicks Delete on a row", () => {
    stubGet([
      {
        id: "20",
        measureName: "EWI",
        orderedAt: "2026-05-01T00:00:00.000Z",
        completedAt: null,
      },
    ]);
    stubDelete("20");
    openDealPageAtPibiTab();
    cy.wait("@getPibiRequests");

    cy.get("[data-testid=pibi-delete-20]").click();
    cy.wait("@deletePibiRequest-20");
  });

  // ── Cycle 7: Add row → POST ───────────────────────────────────────────────

  it("appends a blank row on add-row click and POSTs on save", () => {
    stubGet([]);
    stubPost({ ok: true, insertedCount: 1, hubspotSync: "ok" });
    cy.intercept("GET", `/api/portfolio/${PORTFOLIO_ID_GLOB}/pibi-requests*`, {
      body: {
        pibiRequests: [
          {
            id: "99",
            measureName: "ASHP",
            orderedAt: new Date().toISOString(),
            completedAt: null,
          },
        ],
      },
    }).as("getPibiRequestsAfter");

    openDealPageAtPibiTab();
    cy.wait("@getPibiRequests");

    cy.get("[data-testid=pibi-empty-add-row]").click();
    cy.get("[data-testid=pibi-section]").find("tr[data-testid^=pibi-row-new]").should("have.length", 1);

    cy.get("[data-testid=pibi-section]")
      .find("[data-testid^=pibi-save-new]")
      .click();

    cy.wait("@postPibiRequest").then((interception) => {
      expect(interception.request.body.measureNames).to.be.an("array").with.length(1);
      expect(interception.request.body.orderedAt).to.be.a("string");
    });
  });

  // ── Cycle 8: Mark all complete ────────────────────────────────────────────

  it("PATCHes all incomplete rows when Mark all complete is clicked", () => {
    stubGet([
      {
        id: "30",
        measureName: "ASHP",
        orderedAt: "2026-05-01T00:00:00.000Z",
        completedAt: null,
      },
      {
        id: "31",
        measureName: "CWI",
        orderedAt: "2026-05-01T00:00:00.000Z",
        completedAt: null,
      },
    ]);
    stubPatch("30");
    stubPatch("31");
    openDealPageAtPibiTab();
    cy.wait("@getPibiRequests");

    cy.get("[data-testid=pibi-mark-all-complete]").click();
    cy.wait("@patchPibiRequest-30").then((i) => {
      expect(i.request.body.completedAt).to.be.a("string");
    });
    cy.wait("@patchPibiRequest-31");
  });

  // ── Cycle 9: Scope badges ─────────────────────────────────────────────────

  it("shows Approved badge for a measure in approvedMeasures", () => {
    stubGet([
      {
        id: "40",
        measureName: "ASHP",
        orderedAt: "2026-05-01T00:00:00.000Z",
        completedAt: null,
      },
    ]);
    stubMeasures(["ASHP"], []);
    openDealPageAtPibiTab();
    cy.wait("@getPibiRequests");

    cy.get("[data-testid=pibi-row-40]").should("contain.text", "Approved");
  });
});
