// Mocks the admin API via cy.intercept — no live backend.

const adminBody = {
  id: 1,
  email: "ops@example.com",
  name: "Ops",
  createdAt: "2026-08-01T00:00:00.000Z",
  lastLoginAt: "2026-08-28T09:00:00.000Z",
};

function suggestionGroups() {
  return [
    {
      techStepKey: "simmer",
      suggestions: [
        {
          id: 11,
          techStepKey: "simmer",
          locale: "fr",
          suggestedSynonyms: ["frémir"],
          suggestedUtterances: ["laisser cuire tout doucement"],
          sourceType: "correction",
          status: "pending",
          createdAt: "2026-08-20T00:00:00.000Z",
          sourceCorrection: {
            id: 5,
            recipeId: 2,
            stepId: 7,
            clauseText: "faire mijoter la sauce",
            previousTechStepKey: "cook",
            correctedTechStepKey: "simmer",
          },
        },
      ],
    },
  ];
}

function corrections() {
  return [
    {
      id: 5,
      recipeId: 2,
      stepId: 7,
      stepDescription: "Faire mijoter la sauce 20 min.",
      clauseText: "faire mijoter la sauce",
      start: 0,
      end: 21,
      previousTechStepKey: "cook",
      correctedTechStepKey: "simmer",
      createdAt: "2026-08-20T00:00:00.000Z",
      consumedAt: null,
    },
    {
      id: 6,
      recipeId: 3,
      stepId: 9,
      stepDescription: "Réserver au frais.",
      clauseText: "Réserver au frais",
      start: 0,
      end: 17,
      previousTechStepKey: "setAside",
      correctedTechStepKey: null,
      createdAt: "2026-08-19T00:00:00.000Z",
      consumedAt: null,
    },
  ];
}

describe("Admin corrections triage", () => {
  beforeEach(() => {
    cy.viewport(1400, 1000);
    cy.intercept("GET", "**/admin/auth/me", { statusCode: 200, body: adminBody });
    cy.intercept("GET", "**/admin/tech-steps/suggestions*", {
      statusCode: 200,
      body: suggestionGroups(),
    }).as("getSuggestions");
    cy.intercept("GET", "**/admin/tech-steps/corrections*", {
      statusCode: 200,
      body: corrections(),
    }).as("getCorrections");
  });

  it("shows the caveat, groups suggestions by technique, and applies one", () => {
    cy.intercept("PATCH", "**/admin/tech-steps/suggestions/11", {
      statusCode: 200,
      body: { ...suggestionGroups()[0].suggestions[0], status: "applied" },
    }).as("patch");

    cy.visit("/admin/corrections");
    cy.wait("@getSuggestions");

    cy.contains(".corrections-caveat", "training_data.py").should("be.visible");
    cy.contains(".suggestion-group h2", "simmer").should("be.visible");
    cy.contains(".suggestion-card", "faire mijoter la sauce").should(
      "contain.text",
      "cook → simmer",
    );

    cy.contains(".suggestion-card button", "Appliquer").click();
    cy.wait("@patch").its("request.body").should("deep.equal", { status: "applied" });
  });

  it("generates a training_data.py snippet", () => {
    cy.intercept("GET", "**/admin/tech-steps/training-data-snippet*", {
      statusCode: 200,
      body: {
        techStepKey: "simmer",
        locale: "fr",
        status: "applied",
        suggestionCount: 2,
        synonyms: ["frémir", "réduire"],
        utterances: [],
        snippet:
          '# simmer (fr) — 2 suggestion(s) "applied"\n"synonyms": [\n    "frémir",\n    "réduire",\n],',
      },
    }).as("getSnippet");

    cy.visit("/admin/corrections");
    cy.get(".corrections-panel input").type("simmer");
    cy.contains(".corrections-panel button", "Générer").click();
    cy.wait("@getSnippet");
    cy.get(".corrections-snippet").should("contain.value", '"synonyms": [');
  });

  it("runs the F1 gate and shows the result", () => {
    cy.intercept("POST", "**/admin/tech-steps/retrain", {
      statusCode: 200,
      body: {
        f1: 0.83,
        precision: 0.8,
        recall: 0.86,
        minF1: 0.8,
        gatePassed: true,
        backfilled: { total: 120, changed: 4 },
        marked: { applied: 0, rejected: 0 },
      },
    }).as("retrain");

    cy.visit("/admin/corrections");
    cy.contains(".corrections-panel--retrain button", "Lancer").click();
    cy.wait("@retrain");
    cy.contains(".retrain-result", "F1 0.830")
      .should("have.class", "retrain-result--ok")
      .and("contain.text", "4/120");
  });

  it("lists raw corrections including the removals, on the second tab", () => {
    cy.visit("/admin/corrections");
    cy.contains(".corrections-tabs button", "Corrections brutes").click();
    cy.wait("@getCorrections");

    cy.get(".corrections-table tbody tr").should("have.length", 2);
    cy.contains(".corrections-table tr", "Réserver au frais").should(
      "contain.text",
      "setAside → ∅",
    );
  });
});
