/// <reference types="cypress" />

const makeCustomer = (overrides: Partial<Record<string, any>> = {}, index = 1) => ({
  id: `507f1f77bcf86cd7994390${String(index).padStart(2, "0")}`,
  full_name: `Customer ${index}`,
  email: `customer${index}@example.com`,
  username: `customer${index}`,
  phone: "1234567890",
  type: "individual",
  status: "active",
  role: "admin",
  companies: [],
  created_at: 1710000000 + index,
  updated_at: 1710000500 + index,
  ...overrides,
});

const makeCompany = (overrides: Partial<Record<string, any>> = {}, index = 1) => ({
  id: `company-${index}`,
  name: `Company ${index}`,
  email: `company${index}@example.com`,
  phone: "1234567890",
  website: "https://example.com",
  type: "vendor",
  description: "Test company",
  founded_year: 2020,
  employee_count: 25,
  annual_revenue: 1000000,
  currency: "USD",
  industry: "Technology",
  language: "en",
  tax_id: `TAX-${index}`,
  registration_number: `REG-${index}`,
  timezone: "UTC",
  address: {
    street: "Main St",
    city: "Tehran",
    state: "Tehran",
    postal_code: "12345",
    country: "IR",
  },
  contact_person: {
    full_name: "Jane Doe",
    first_name: "Jane",
    last_name: "Doe",
    email: "jane.doe@example.com",
    phone: "1234567890",
    mobile: "1234567890",
    position: "Manager",
    is_primary: true,
  },
  tags: {
    keywords: [],
    categories: [],
    specializations: [],
    certifications: [],
    cpv_codes: [],
  },
  ...overrides,
});

const customersResponse = ({
  customers,
  offset = 0,
  limit = 10,
  total = customers.length,
  pages = Math.max(1, Math.ceil(total / limit)),
}: {
  customers: Record<string, any>[];
  offset?: number;
  limit?: number;
  total?: number;
  pages?: number;
}) => ({
  success: true,
  message: "ok",
  data: { customers },
  meta: { offset, limit, total, pages, page: Math.floor(offset / limit) + 1 },
});

describe("customers management - list, actions, filters, feedback", () => {
  beforeEach(() => {
    cy.setAuthCookies();
  });

  it("renders table columns and row data from API", () => {
    const customers = [
      makeCustomer(
        {
          full_name: "John Carter",
          email: "john.carter@example.com",
          companies: [{ id: "c1", name: "Acme" }],
        },
        1,
      ),
      makeCustomer({ status: "inactive", role: "analyst" }, 2),
    ];

    cy.intercept("GET", "**/api/proxy/customers**", {
      statusCode: 200,
      body: customersResponse({ customers }),
    }).as("getCustomers");

    cy.visit("/customers");
    cy.wait("@getCustomers");

    [
      "row",
      "full name",
      "email",
      "created at",
      "type",
      "status",
      "company",
      "role",
      "actions",
    ].forEach((header) => cy.contains("th", new RegExp(`^${header}$`, "i")).should("be.visible"));

    cy.contains("John Carter").should("be.visible");
    cy.contains("john.carter@example.com").should("be.visible");
    cy.contains("Acme").should("be.visible");
  });

  it("shows empty state when API returns no customers", () => {
    cy.intercept("GET", "**/api/proxy/customers**", {
      statusCode: 200,
      body: customersResponse({ customers: [], total: 0 }),
    }).as("getCustomersEmpty");

    cy.visit("/customers");
    cy.wait("@getCustomersEmpty");

    cy.getByCy("empty-list-message").should("contain", "No Customers were found");
  });

  it("shows loading skeleton while list request is in flight", () => {
    cy.intercept("GET", "**/api/proxy/customers**", (req) => {
      req.reply({
        delay: 1200,
        statusCode: 200,
        body: customersResponse({ customers: [makeCustomer()] }),
      });
    }).as("getCustomersSlow");

    cy.visit("/customers");
    cy.getByCy("table-skeleton").should("be.visible");
    cy.wait("@getCustomersSlow");
    cy.getByCy("table-skeleton").should("not.exist");
  });

  it("paginates with correct offset when moving to next page", () => {
    const pageOne = Array.from({ length: 10 }).map((_, i) => makeCustomer({}, i + 1));
    const pageTwo = [makeCustomer({ id: "507f1f77bcf86cd799439099", full_name: "Page 2 Customer" }, 99)];

    cy.intercept("GET", "**/api/proxy/customers**", (req) => {
      const offset = Number(req.query.offset ?? 0);
      if (offset === 10) {
        req.alias = "getCustomersPage2";
        req.reply({
          statusCode: 200,
          body: customersResponse({
            customers: pageTwo,
            offset: 10,
            limit: 10,
            total: 11,
            pages: 2,
          }),
        });
        return;
      }
      req.alias = "getCustomersPage1";
      req.reply({
        statusCode: 200,
        body: customersResponse({
          customers: pageOne,
          offset: 0,
          limit: 10,
          total: 11,
          pages: 2,
        }),
      });
    });

    cy.visit("/customers");
    cy.wait("@getCustomersPage1");
    cy.contains("Page 2 Customer").should("not.exist");
    cy.contains("›").click();
    cy.wait("@getCustomersPage2")
      .its("request.query.offset")
      .should("eq", "10");
    cy.contains("Page 2 Customer").should("be.visible");
  });

  it("deletes customer with confirm modal and sends correct request", () => {
    const customer = makeCustomer({ id: "507f1f77bcf86cd799439066", full_name: "Delete Me" }, 66);

    cy.intercept("GET", "**/api/proxy/customers**", {
      statusCode: 200,
      body: customersResponse({ customers: [customer] }),
    }).as("getCustomers");

    cy.intercept("DELETE", `**/api/proxy/customers/${customer.id}`, {
      statusCode: 200,
      body: { success: true, data: { message: "Customer deleted successfully" } },
    }).as("deleteCustomer");

    cy.visit("/customers");
    cy.wait("@getCustomers");
    cy.contains("Delete Me").should("be.visible");

    cy.get('button[data-tooltip-id="delete"]').first().click();
    cy.getByCy("confirmation-modal").should("be.visible");
    cy.getByCy("confirmation-modal-cancel").click();
    cy.getByCy("confirmation-modal").should("not.exist");

    cy.intercept("GET", "**/api/proxy/customers**", {
      statusCode: 200,
      body: customersResponse({ customers: [], total: 0 }),
    }).as("getCustomersAfterDelete");

    cy.get('button[data-tooltip-id="delete"]').first().click();
    cy.getByCy("confirmation-modal-confirm").click();
    cy.wait("@deleteCustomer");
    cy.wait("@getCustomersAfterDelete");
    cy.getByCy("empty-list-message").should("contain", "No Customers were found");
  });

  it("assigns customer to company with correct payload", () => {
    const customer = makeCustomer(
      { id: "507f1f77bcf86cd799439033", companies: [{ id: "comp-2", name: "Global LLC" }] },
      33,
    );
    const companies = [
      makeCompany({ id: "comp-1", name: "Acme Corp" }, 1),
      makeCompany({ id: "comp-2", name: "Global LLC" }, 2),
    ];

    cy.intercept("GET", "**/api/proxy/customers**", {
      statusCode: 200,
      body: customersResponse({ customers: [customer] }),
    }).as("getCustomers");

    cy.intercept("GET", "**/api/proxy/companies**", {
      statusCode: 200,
      body: {
        success: true,
        message: "ok",
        data: { companies },
        meta: { offset: 0, limit: 10, total: companies.length },
      },
    }).as("getCompanies");

    cy.intercept("POST", `**/api/proxy/customers/${customer.id}/companies`, (req) => {
      expect(req.body).to.deep.equal({ company_ids: ["comp-2"] });
      req.reply({
        statusCode: 200,
        body: { success: true, message: "Selected Companies were assigned", data: {} },
      });
    }).as("assignCompany");

    cy.visit("/customers");
    cy.wait("@getCustomers");
    cy.get('button[data-tooltip-id="assign-company"]').first().click();
    cy.wait("@getCompanies");
    cy.getByCy("modal-confirm-button").click();
    cy.wait("@assignCompany");
  });

  it("surfaces assign-company API failures (404)", () => {
    const customer = makeCustomer(
      { id: "507f1f77bcf86cd799439034", companies: [{ id: "comp-1", name: "Acme Corp" }] },
      34,
    );

    cy.intercept("GET", "**/api/proxy/customers**", {
      statusCode: 200,
      body: customersResponse({ customers: [customer] }),
    }).as("getCustomers");

    cy.intercept("GET", "**/api/proxy/companies**", {
      statusCode: 200,
      body: {
        success: true,
        message: "ok",
        data: { companies: [makeCompany({ id: "comp-1", name: "Acme Corp" }, 1)] },
      },
    }).as("getCompanies");

    cy.intercept("POST", `**/api/proxy/customers/${customer.id}/companies`, {
      statusCode: 404,
      body: { error: { message: "Route not found" } },
    }).as("assignCompany404");

    cy.visit("/customers");
    cy.wait("@getCustomers");
    cy.get('button[data-tooltip-id="assign-company"]').first().click();
    cy.wait("@getCompanies");
    cy.getByCy("modal-confirm-button").click();
    cy.wait("@assignCompany404").its("response.statusCode").should("eq", 404);
    cy.getByCy("modal-content").should("be.visible");
  });

  it("applies status/role/type filters and keeps close action side-effect free", () => {
    const unfiltered = [makeCustomer({ full_name: "Unfiltered Customer" }, 11)];
    const filtered = [makeCustomer({ full_name: "Filtered Customer", status: "inactive" }, 12)];

    cy.intercept("GET", "**/api/proxy/customers**", (req) => {
      const isFiltered =
        req.query.status === "inactive" &&
        req.query.role === "analyst" &&
        req.query.type === "company";
      req.alias = isFiltered ? "getCustomersFiltered" : "getCustomersDefault";
      req.reply({
        statusCode: 200,
        body: customersResponse({
          customers: isFiltered ? filtered : unfiltered,
          total: 1,
        }),
      });
    });

    cy.visit("/customers");
    cy.wait("@getCustomersDefault");

    cy.contains("button", "Filter").click();
    cy.get('select[name="status"]').select("inactive");
    cy.get('select[name="role"]').select("analyst");
    cy.get('select[name="type"]').select("company");
    cy.contains("button", "Search").click();

    cy.wait("@getCustomersFiltered");
    cy.contains("Filtered Customer").should("be.visible");

    cy.contains("button", "Filter").click();
    cy.contains("button", "Close").click();
    cy.get("@getCustomersFiltered.all").should("have.length", 1);
  });

  it("navigates to feedback page and loads customer feedback list", () => {
    const customer = makeCustomer({ id: "507f1f77bcf86cd799439044", full_name: "Feedback Target" }, 44);

    cy.intercept("GET", "**/api/proxy/customers**", {
      statusCode: 200,
      body: customersResponse({ customers: [customer] }),
    }).as("getCustomers");

    cy.intercept("GET", "**/api/proxy/feedback**", (req) => {
      expect(req.query.customer_id).to.eq(customer.id);
      req.reply({
        statusCode: 200,
        body: {
          success: true,
          message: "ok",
          data: [
            {
              id: "fb-1",
              feedback_type: "bug",
              created_at: 1710001000,
              updated_at: 1710001200,
            },
          ],
        },
      });
    }).as("getCustomerFeedback");

    cy.visit("/customers");
    cy.wait("@getCustomers");
    cy.get('button[data-tooltip-id="feedback"]').first().click();
    // Route transition can be delayed in headless runs.
    cy.location("pathname", { timeout: 15000 }).should(
      "eq",
      `/customers/feedback/${customer.id}`,
    );
    cy.wait("@getCustomerFeedback");
    cy.contains("feedback type").should("be.visible");
  });
});
