import { effectivePermitLocation } from "./dashboardHelpers.js";

export const PERMIT_DATE_PRESETS = [
  { value: "", label: "All dates" },
  { value: "7d", label: "Last 7 days" },
  { value: "30d", label: "Last 30 days" },
  { value: "90d", label: "Last 90 days" },
  { value: "year", label: "This year" },
  { value: "custom", label: "Custom range" }
];

function toDateInputValue(date) {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, "0");
  const d = String(date.getDate()).padStart(2, "0");
  return `${y}-${m}-${d}`;
}

export function resolvePermitDateRange(preset, customFrom = "", customTo = "") {
  if (!preset) {
    return { dateFrom: "", dateTo: "" };
  }
  if (preset === "custom") {
    return { dateFrom: customFrom || "", dateTo: customTo || "" };
  }

  const now = new Date();
  const dateTo = toDateInputValue(now);
  const from = new Date(now);

  if (preset === "7d") {
    from.setDate(from.getDate() - 6);
  } else if (preset === "30d") {
    from.setDate(from.getDate() - 29);
  } else if (preset === "90d") {
    from.setDate(from.getDate() - 89);
  } else if (preset === "year") {
    from.setMonth(0, 1);
  }

  return { dateFrom: toDateInputValue(from), dateTo };
}

export function buildPermitJobTypeMap(submissions = [], forms = []) {
  const formJobType = Object.fromEntries(
    (Array.isArray(forms) ? forms : [])
      .filter((form) => form?.form_id != null && form?.job_type_id != null)
      .map((form) => [Number(form.form_id), Number(form.job_type_id)])
  );

  const map = new Map();
  for (const row of Array.isArray(submissions) ? submissions : []) {
    const permitId = Number(row.permit_id);
    const jobTypeId = formJobType[Number(row.form_id)];
    if (!Number.isFinite(permitId) || !jobTypeId) continue;
    if (!map.has(permitId)) map.set(permitId, new Set());
    map.get(permitId).add(jobTypeId);
  }
  return map;
}

export function normalizeLocationRow(row) {
  if (row == null || typeof row !== "object") return null;
  const locationId = row.location_id ?? row.locationId ?? row.id;
  if (locationId == null || locationId === "") return null;
  const locationName =
    row.location_name ??
    row.Location_name ??
    row.locationName ??
    row.name ??
    "";
  const countryId = row.country_id ?? row.countryId ?? null;
  const id = Number(locationId);
  return {
    location_id: id,
    location_name: String(locationName).trim() || `Location #${id}`,
    country_id: countryId != null && countryId !== "" ? Number(countryId) : null
  };
}

export function normalizeCountryRow(row) {
  if (row == null || typeof row !== "object") return null;
  const countryId = row.country_id ?? row.countryId ?? row.id;
  if (countryId == null || countryId === "") return null;
  const countryName =
    row.country_name ??
    row.Country_name ??
    row.countryName ??
    row.name ??
    "";
  const id = Number(countryId);
  return {
    country_id: id,
    country_name: String(countryName).trim() || `Country #${id}`
  };
}

export function resolveCountryIdFromUserLocation(user, locations = []) {
  const locationId = user?.location_id != null ? Number(user.location_id) : null;
  if (!Number.isFinite(locationId) || locationId <= 0) return "";
  const match = (Array.isArray(locations) ? locations : []).find(
    (row) => Number(row.location_id) === locationId
  );
  return match?.country_id != null ? String(match.country_id) : "";
}

export function filterLocationsByCountry(locations = [], countryId = "") {
  const list = Array.isArray(locations) ? locations : [];
  if (!countryId) return list;
  const target = Number(countryId);
  return list.filter((row) => Number(row.country_id) === target);
}

export function buildLocationCountryById(locations = []) {
  return Object.fromEntries(
    (Array.isArray(locations) ? locations : [])
      .filter((row) => row?.location_id != null)
      .map((row) => [
        String(row.location_id),
        row.country_id != null ? Number(row.country_id) : null
      ])
  );
}

export function permitMatchesCountry(row, countryId, locationCountryById = {}) {
  if (!countryId) return true;
  const target = Number(countryId);
  if (row?.country_id != null && Number(row.country_id) === target) return true;
  if (row?.location_country_id != null && Number(row.location_country_id) === target) {
    return true;
  }
  const locationId = row?.location_id != null ? String(row.location_id) : "";
  if (locationId && locationCountryById[locationId] === target) return true;
  return false;
}

export function buildLocationFilterOptions(locations = [], permits = [], { countryId = "" } = {}) {
  const normalized = (Array.isArray(locations) ? locations : [])
    .map((raw) => normalizeLocationRow(raw))
    .filter(Boolean);
  const locationCountryById = buildLocationCountryById(normalized);
  const scopedLocations = filterLocationsByCountry(normalized, countryId);
  const byId = new Map();

  for (const row of scopedLocations) {
    byId.set(row.location_id, row);
  }

  for (const permit of Array.isArray(permits) ? permits : []) {
    const id = permit?.location_id != null ? Number(permit.location_id) : null;
    if (!Number.isFinite(id) || id <= 0 || byId.has(id)) continue;
    if (countryId) {
      const permitCountry =
        permit.location_country_id ??
        permit.country_id ??
        locationCountryById[String(id)];
      if (Number(permitCountry) !== Number(countryId)) continue;
    }
    const name =
      permit.location_name ??
      permit.Location_name ??
      permit.locationName ??
      "";
    byId.set(id, {
      location_id: id,
      location_name: String(name).trim() || `Location #${id}`,
      country_id: countryId ? Number(countryId) : locationCountryById[String(id)] ?? null
    });
  }

  return [...byId.values()].sort((a, b) =>
    a.location_name.localeCompare(b.location_name)
  );
}

export function buildLocationNameById(locations = [], permits = []) {
  return Object.fromEntries(
    buildLocationFilterOptions(locations, permits).map((row) => [
      String(row.location_id),
      row.location_name
    ])
  );
}

export function buildCountryNameById(countries = []) {
  return Object.fromEntries(
    (Array.isArray(countries) ? countries : [])
      .map((raw) => normalizeCountryRow(raw))
      .filter(Boolean)
      .map((row) => [String(row.country_id), row.country_name])
  );
}

function parsePermitDate(raw) {
  if (!raw) return null;
  const date = new Date(raw);
  return Number.isNaN(date.getTime()) ? null : date;
}

export function permitMatchesDateRange(row, dateFrom, dateTo) {
  if (!dateFrom && !dateTo) return true;
  const created = parsePermitDate(row?.created_at);
  if (!created) return false;

  if (dateFrom) {
    const from = new Date(`${dateFrom}T00:00:00`);
    if (created < from) return false;
  }
  if (dateTo) {
    const to = new Date(`${dateTo}T23:59:59.999`);
    if (created > to) return false;
  }
  return true;
}

export function filterPermitsByPageFilters(
  permits,
  {
    countryId = "",
    locationId = "",
    jobTypeId = "",
    dateFrom = "",
    dateTo = "",
    jobTypeMap = new Map(),
    locationCountryById = {}
  } = {}
) {
  let list = Array.isArray(permits) ? permits : [];

  if (countryId) {
    list = list.filter((row) => permitMatchesCountry(row, countryId, locationCountryById));
  }

  if (locationId) {
    const target = Number(locationId);
    list = list.filter((row) => {
      const effective = effectivePermitLocation(row);
      return effective != null ? effective === target : Number(row.location_id) === target;
    });
  }

  if (jobTypeId) {
    const target = Number(jobTypeId);
    list = list.filter((row) => jobTypeMap.get(Number(row.permit_id))?.has(target));
  }

  if (dateFrom || dateTo) {
    list = list.filter((row) => permitMatchesDateRange(row, dateFrom, dateTo));
  }

  return list;
}

export function findJobTypeIdByName(jobTypes, name) {
  const needle = String(name || "").trim().toLowerCase();
  if (!needle) return "";
  const match = (Array.isArray(jobTypes) ? jobTypes : []).find(
    (row) => String(row.job_type_name || "").trim().toLowerCase() === needle
  );
  return match?.job_type_id != null ? String(match.job_type_id) : "";
}

export function formatPermitJobTypes(permitId, jobTypeMap, jobTypeNameById) {
  const ids = [...(jobTypeMap.get(Number(permitId)) || [])];
  if (!ids.length) return "—";
  return ids
    .map((id) => jobTypeNameById[String(id)] || `#${id}`)
    .sort((a, b) => a.localeCompare(b))
    .join(", ");
}
