import test from "node:test";
import assert from "node:assert/strict";

import { discoverListingSources } from "../src/listing-discovery.js";
import { extractPhotoData } from "../src/photo-review.js";

test("discoverListingSources times out stalled Zillow and HAR discovery calls", async () => {
  const result = await discoverListingSources(
    "1011 Ennis Joslin Rd APT 235, Corpus Christi, TX 78412",
    {
      timeoutMs: 20,
      discoverZillowListingFn: async () => await new Promise(() => {}),
      discoverHarListingFn: async () => await new Promise(() => {})
    }
  );

  assert.equal(result.zillowUrl, null);
  assert.equal(result.harUrl, null);
  assert.match(result.attempts.join(" "), /zillow discovery timed out/i);
  assert.match(result.attempts.join(" "), /har discovery timed out/i);
});

test("discoverListingSources starts Zillow and HAR discovery in parallel", async () => {
  let zillowStarted = false;
  let harStarted = false;

  const discoveryPromise = discoverListingSources("1011 Ennis Joslin Rd APT 235, Corpus Christi, TX 78412", {
    timeoutMs: 100,
    discoverZillowListingFn: async () => {
      zillowStarted = true;
      await new Promise((resolve) => setTimeout(resolve, 50));
      return {
        source: "zillow",
        address: "1011 Ennis Joslin Rd APT 235, Corpus Christi, TX 78412",
        searchUrl: "https://www.zillow.com/example-search",
        finalUrl: "https://www.zillow.com/example-search",
        title: "Example Zillow Search",
        listingUrl: null,
        attempts: ["Zillow did not find a confident match."]
      };
    },
    discoverHarListingFn: async () => {
      harStarted = true;
      return {
        source: "har",
        address: "1011 Ennis Joslin Rd APT 235, Corpus Christi, TX 78412",
        searchUrl: "https://www.har.com/example-search",
        finalUrl: "https://www.har.com/example-search",
        title: "Example HAR Search",
        listingUrl: "https://www.har.com/homedetail/example/123",
        attempts: ["HAR found a matching listing quickly."]
      };
    }
  });

  await new Promise((resolve) => setTimeout(resolve, 10));

  assert.equal(zillowStarted, true);
  assert.equal(harStarted, true);

  const result = await discoveryPromise;
  assert.equal(result.harUrl, "https://www.har.com/homedetail/example/123");
});

test("extractPhotoData honors a longer Zillow timeout override", async () => {
  const result = await extractPhotoData("zillow", "https://www.zillow.com/example", {
    timeoutMs: 20,
    zillowTimeoutMs: 80,
    extractZillowPhotosFn: async () => {
      await new Promise((resolve) => setTimeout(resolve, 40));
      return {
        source: "zillow",
        requestedUrl: "https://www.zillow.com/example",
        finalUrl: "https://www.zillow.com/example",
        expectedPhotoCount: 1,
        complete: true,
        photoCount: 1,
        imageUrls: ["https://photos.example/1.jpg"],
        notes: ["Zillow extractor succeeded after a slow page load."]
      };
    }
  });

  assert.equal(result.source, "zillow");
  assert.equal(result.photoCount, 1);
});

test("extractPhotoData times out a stalled photo extraction instead of hanging forever", async () => {
  await assert.rejects(
    async () =>
      extractPhotoData("zillow", "https://www.zillow.com/example", {
        timeoutMs: 20,
        extractZillowPhotosFn: async () => await new Promise(() => {})
      }),
    /timed out/i
  );
});
