/**
 * Integration tests for SEO output in the Online Board.
 *
 * Uses renderToString to verify that SeoHead produces expected
 * title, description, canonical, OG tags, hreflang, and JSON-LD
 * in the rendered HTML.
 *
 * @vitest-environment jsdom
 */

import { describe, it, expect, vi } from "vitest";
import { renderToString } from "react-dom/server";
import React from "react";
import { SeoHead } from "@/ui/seo/SeoHead.js";
import {
  buildOnlineBoardStartSeo,
  buildFlightSearchSeo,
  buildDepartureSearchSeo,
  buildFlightDetailsSeo,
} from "@/features/online-board/seo.js";
import { buildFlightJsonLd, buildFlightListJsonLd } from "@/features/online-board/json-ld.js";
import { DIRECT_FLIGHT, ALL_FLIGHTS } from "./fixtures.js";

// ---------------------------------------------------------------------------
// Stub translation function
// ---------------------------------------------------------------------------

const t = (key: string, opts?: Record<string, string>) => {
  if (opts) {
    let result = key;
    for (const [k, v] of Object.entries(opts)) {
      result += ` ${k}=${v}`;
    }
    return result;
  }
  return key;
};

const LOCALE = "ru";
const ORIGIN = "https://www.aeroflot.ru";

// ---------------------------------------------------------------------------
// Tests — SeoHead rendering
// ---------------------------------------------------------------------------

describe("SEO integration — SeoHead SSR output", () => {
  it("renders title for start page", () => {
    const seoProps = buildOnlineBoardStartSeo(t, LOCALE, ORIGIN);
    const html = renderToString(React.createElement(SeoHead, seoProps));

    expect(html).toContain("SEO.BOARD.MAIN.TITLE");
  });

  it("renders meta description for start page", () => {
    const seoProps = buildOnlineBoardStartSeo(t, LOCALE, ORIGIN);
    const html = renderToString(React.createElement(SeoHead, seoProps));

    expect(html).toContain('name="description"');
    expect(html).toContain("SEO.BOARD.MAIN.DESCRIPTION");
  });

  it("renders canonical link for start page", () => {
    const seoProps = buildOnlineBoardStartSeo(t, LOCALE, ORIGIN);
    const html = renderToString(React.createElement(SeoHead, seoProps));

    expect(html).toContain('rel="canonical"');
    expect(html).toContain("https://www.aeroflot.ru/ru/onlineboard");
  });

  it("renders OG tags for flight search page", () => {
    const seoProps = buildFlightSearchSeo(
      t,
      { type: "flight", carrier: "SU", flightNumber: "100", date: "20250115" },
      LOCALE,
      ORIGIN,
    );
    const html = renderToString(React.createElement(SeoHead, seoProps));

    expect(html).toContain('property="og:title"');
    expect(html).toContain('property="og:description"');
    expect(html).toContain('property="og:url"');
    expect(html).toContain('property="og:image"');
    expect(html).toContain('property="og:type" content="website"');
    expect(html).toContain('property="og:locale" content="ru"');
    expect(html).toContain('property="og:site_name" content="Aeroflot"');
  });

  it("renders hreflang links for departure search page", () => {
    const seoProps = buildDepartureSearchSeo(
      t,
      { type: "departure", station: "SVO", date: "20250115" },
      LOCALE,
      ORIGIN,
    );
    const html = renderToString(React.createElement(SeoHead, seoProps));

    // React renders the JSX prop `hrefLang` as the HTML attribute `hrefLang` (camelCase) in SSR
    expect(html).toContain('hrefLang="ru"');
    expect(html).toContain('hrefLang="en"');
    expect(html).toContain('hrefLang="x-default"');
  });

  it("renders twitter card meta tag", () => {
    const seoProps = buildOnlineBoardStartSeo(t, LOCALE, ORIGIN);
    const html = renderToString(React.createElement(SeoHead, seoProps));

    expect(html).toContain('name="twitter:card" content="summary"');
  });

  it("renders canonical with correct flight URL for details", () => {
    const seoProps = buildFlightDetailsSeo(t, DIRECT_FLIGHT, LOCALE, ORIGIN);
    const html = renderToString(React.createElement(SeoHead, seoProps));

    expect(html).toContain('rel="canonical"');
    expect(html).toContain("https://www.aeroflot.ru/ru/onlineboard/SU0100-20250115");
  });
});

// ---------------------------------------------------------------------------
// Tests — JSON-LD rendering
// ---------------------------------------------------------------------------

describe("SEO integration — JSON-LD output", () => {
  it("produces valid JSON-LD for a single flight", () => {
    const jsonLd = buildFlightJsonLd(DIRECT_FLIGHT);
    const json = JSON.stringify(jsonLd);

    expect(json).toContain("@type");
    expect(json).toContain("Flight");
  });

  it("produces valid JSON-LD for flight list", () => {
    const jsonLd = buildFlightListJsonLd(ALL_FLIGHTS, "Departure flights from SVO");
    const json = JSON.stringify(jsonLd);

    expect(json).toContain("@type");
    expect(json).toContain("ItemList");
  });

  it("includes flight number in single flight JSON-LD", () => {
    const jsonLd = buildFlightJsonLd(DIRECT_FLIGHT);
    const json = JSON.stringify(jsonLd);

    // Should contain the flight number somewhere in the JSON-LD
    expect(json).toContain("SU");
  });

  it("includes departure and arrival airports in JSON-LD", () => {
    const jsonLd = buildFlightJsonLd(DIRECT_FLIGHT);
    const json = JSON.stringify(jsonLd);

    expect(json).toContain("SVO");
    expect(json).toContain("JFK");
  });
});
