import type { HotDeal, ValidationIssue } from "./types";

export function validateDeal(deal: HotDeal): ValidationIssue[] {
  const issues: ValidationIssue[] = [];
  const keys = Object.keys(deal);

  if (!deal.resort) {
    issues.push({ severity: "error", message: "Missing resort name" });
  }

  if (!deal.travel_between || deal.travel_between.length === 0) {
    issues.push({ severity: "error", message: "No travel dates defined" });
  }

  const hasOccpPrice = keys.includes("occp_price");
  const hasOccpPriceXXX = keys.some(
    (k) => k.startsWith("occp_price") && k !== "occp_price",
  );
  if (hasOccpPriceXXX && !hasOccpPrice) {
    issues.push({
      severity: "error",
      message:
        'Price matrix is disabled (key is "occp_priceXXX"). Enable it on the Pricing tab.',
    });
  }

  if (!hasOccpPrice && deal.price === undefined) {
    issues.push({
      severity: "warning",
      message: "No pricing defined (no occp_price and no flat price)",
    });
  }

  const xxxKeys = keys.filter((k) => k !== "id" && k.includes("XXX"));
  for (const k of xxxKeys) {
    if (k.startsWith("occp_price")) {
      // already reported above if no occp_price
    } else {
      issues.push({
        severity: "warning",
        message: `Field "${k}" is disabled (contains XXX)`,
      });
    }
  }

  if (deal.unit_code) {
    const disabledUnits = deal.unit_code.filter((u) => u.includes("XXX"));
    for (const u of disabledUnits) {
      issues.push({
        severity: "warning",
        message: `Unit code "${u}" is disabled (contains XXX)`,
      });
    }
  }

  if (deal.override) {
    for (const [blockKey, block] of Object.entries(deal.override)) {
      if (blockKey.includes("XXX")) {
        issues.push({
          severity: "warning",
          message: `Override block "${blockKey}" is disabled`,
        });
      } else if (block.settings) {
        for (const settingKey of Object.keys(block.settings)) {
          if (settingKey.includes("XXX")) {
            issues.push({
              severity: "warning",
              message: `Override "${blockKey}" has disabled setting "${settingKey}"`,
            });
          }
        }
      }
    }
  }

  const hasStarts = keys.some((k) => k.startsWith("starts"));
  if (!hasStarts) {
    issues.push({
      severity: "warning",
      message: "No booking start date found (not even a disabled one)",
    });
  }

  if (
    deal.travel_between &&
    deal.travel_between.length > 0 &&
    deal.master_info
  ) {
    const firstStart = deal.travel_between[0]?.[0];
    const lastEnd = deal.travel_between[deal.travel_between.length - 1]?.[1];

    if (firstStart && deal.master_info.check_in !== firstStart) {
      issues.push({
        severity: "error",
        message: `master_info.check_in (${deal.master_info.check_in || "unset"}) doesn't match travel_between start (${firstStart})`,
      });
    }

    if (lastEnd && deal.master_info.check_out) {
      const checkOut = new Date(deal.master_info.check_out).getTime();
      const travelEnd = new Date(lastEnd).getTime();
      if (Math.abs(checkOut - travelEnd) > 86400000) {
        issues.push({
          severity: "error",
          message: `master_info.check_out (${deal.master_info.check_out}) doesn't match travel_between end (${lastEnd})`,
        });
      }
    } else if (lastEnd && !deal.master_info.check_out) {
      issues.push({
        severity: "error",
        message: "master_info.check_out is unset",
      });
    }

    if (deal.expires && lastEnd) {
      const expires = new Date(deal.expires).getTime();
      const travelEnd = new Date(lastEnd).getTime();
      if (expires < travelEnd - 86400000) {
        issues.push({
          severity: "warning",
          message:
            "Booking window (expires) closes more than 1 day before travel period ends",
        });
      }
    }
  }

  if (deal.expires) {
    const expires = new Date(deal.expires).getTime();
    if (expires < Date.now()) {
      issues.push({
        severity: "info",
        message: "This deal has already expired",
      });
    }
  }

  return issues;
}

export function getDealStatus(deal: HotDeal): import("./types").DealStatus {
  const keys = Object.keys(deal);
  const hasStarts = keys.some((k) => k === "starts");
  if (!hasStarts) return "unknown";

  const now = Date.now();
  const starts = deal.starts ? new Date(deal.starts).getTime() : null;
  const expires = deal.expires ? new Date(deal.expires).getTime() : null;

  if (starts && starts > now) return "upcoming";
  if (expires && expires < now) return "expired";
  if (starts && starts <= now) return "active";
  return "unknown";
}
