export const featureTypes = {
  lotBoundary: {
    label: "Lot Boundary",
    geometryType: "Polygon",
    detailFields: {},
    style: {
      color: "#7b684d",
      weight: 2,
      dashArray: "8 5",
      fillColor: "#dccaab",
      fillOpacity: 0.08,
    },
  },
  fence: {
    label: "Fence",
    geometryType: "LineString",
    detailFields: {
      fenceType: "string",
    },
    style: {
      color: "#705033",
      weight: 4,
      opacity: 0.95,
    },
  },
  yardGrid: {
    label: "Yard Grid",
    geometryType: "LineString",
    detailFields: {
      axis: "string",
      offsetFeet: "number",
      spacingFeet: "number",
    },
    style: (details) => ({
      color: details.offsetFeet === 0 ? "#1f4f63" : "#2f7f98",
      weight: details.offsetFeet === 0 ? 3 : 2,
      opacity: details.offsetFeet === 0 ? 0.75 : 0.55,
      dashArray: details.offsetFeet === 0 ? undefined : "6 5",
    }),
  },
  house: {
    label: "House",
    geometryType: "Polygon",
    detailFields: {},
    style: {
      color: "#8d5a35",
      weight: 2,
      fillColor: "#c98d58",
      fillOpacity: 0.35,
    },
  },
  garage: {
    label: "Garage",
    geometryType: "Polygon",
    detailFields: {},
    style: {
      color: "#60636b",
      weight: 2,
      fillColor: "#a4acb9",
      fillOpacity: 0.45,
    },
  },
  porch: {
    label: "Porch",
    geometryType: "Polygon",
    detailFields: {},
    style: {
      color: "#aa7148",
      weight: 2,
      fillColor: "#deb588",
      fillOpacity: 0.38,
    },
  },
  deck: {
    label: "Deck",
    geometryType: "Polygon",
    detailFields: {},
    style: {
      color: "#7f5a3c",
      weight: 2,
      fillColor: "#b98c66",
      fillOpacity: 0.32,
    },
  },
  walkway: {
    label: "Walkway",
    geometryType: "Polygon",
    detailFields: {},
    style: {
      color: "#b8b3a6",
      weight: 2,
      fillColor: "#d6d1c3",
      fillOpacity: 0.75,
    },
  },
  driveway: {
    label: "Driveway",
    geometryType: "Polygon",
    detailFields: {},
    style: {
      color: "#9c9890",
      weight: 2,
      fillColor: "#bbb7af",
      fillOpacity: 0.8,
    },
  },
  flowerBed: {
    label: "Flower Bed",
    geometryType: "Polygon",
    detailFields: {
      soil: "string",
      mulch: "string",
      sunExposure: "string",
    },
    style: {
      color: "#7f7f31",
      weight: 2,
      fillColor: "#bfc97b",
      fillOpacity: 0.38,
    },
  },
  plant: {
    label: "Plant",
    geometryType: "Point",
    detailFields: {
      commonName: "string",
      genus: "string",
      species: "string",
      cultivar: "string",
      gardenOrgId: "string",
      note: "string",
    },
    externalLinks: [
      {
        label: "Garden.org",
        url: (details) =>
          details.gardenOrgId
            ? `https://garden.org/plants/view/${encodeURIComponent(details.gardenOrgId)}/`
            : null,
      },
    ],
    style: {
      color: "#3d7140",
      weight: 2,
      radius: 5,
      fillColor: "#78a658",
      fillOpacity: 0.8,
    },
  },
  flower: {
    label: "Flower",
    parentKind: "plant",
    geometryType: "Point",
    detailFields: {
      commonName: "string",
      genus: "string",
      species: "string",
      cultivar: "string",
      bloomColor: "string",
      bloomSeason: "string",
      note: "string",
    },
    style: {
      color: "#9c3f74",
      weight: 2,
      fillColor: "#d979aa",
      fillOpacity: 0.85,
      iconUrl: "./src/assets/icons/flower.svg",
      iconDiameterMeters: 0.4,
    },
  },
  daylily: {
    label: "Daylily",
    parentKind: "flower",
    geometryType: "Point",
    detailFields: {
      commonName: "string",
      genus: "string",
      cultivar: "string",
      bloomColor: "string",
      bloomSeason: "string",
      note: "string",
    },
    style: {
      color: "#9f5e1d",
      weight: 2,
      radius: 5,
      fillColor: "#f0b44c",
      fillOpacity: 0.88,
      iconUrl: "./src/assets/icons/daylily.svg",
      iconDiameterMeters: 2.5 / 3.280839895,
    },
  },
  shrub: {
    label: "Shrub",
    parentKind: "plant",
    geometryType: "Point",
    detailFields: {
      commonName: "string",
      genus: "string",
      species: "string",
      cultivar: "string",
      canopyDiameterMeters: "number",
      heightMeters: "number",
      note: "string",
    },
    style: (details) => ({
      color: "#426a3d",
      weight: 1,
      radiusMeters: (details.canopyDiameterMeters ?? 1) / 2,
      fillColor: "#7e9d58",
      fillOpacity: 0.62,
    }),
  },
  tree: {
    label: "Tree",
    parentKind: "plant",
    geometryType: "Point",
    detailFields: {
      commonName: "string",
      genus: "string",
      species: "string",
      cultivar: "string",
      canopyDiameterMeters: "number",
      heightMeters: "number",
      note: "string",
    },
    style: (details) => ({
      color: "#2f6b3d",
      weight: 1,
      radiusMeters: (details.canopyDiameterMeters ?? 2) / 2,
      fillColor: "#5c9e64",
      fillOpacity: 0.55,
    }),
  },
  sprinkler: {
    label: "Sprinkler",
    geometryType: "Point",
    detailFields: {
      zone: "string",
      headType: "string",
      flowRateGallonsPerMinute: "number",
    },
    style: {
      color: "#2d7dd2",
      radius: 5,
      fillColor: "#88bdf2",
      fillOpacity: 0.95,
    },
  },
};

export function getFeatureType(kind) {
  const definition = featureTypes[kind];
  if (!definition) {
    throw new Error(`Unknown feature type: ${kind}`);
  }

  return definition;
}

export function listFeatureTypeSchemas() {
  return Object.entries(featureTypes).map(([kind, definition]) => ({
    kind,
    label: definition.label,
    parentKind: definition.parentKind ?? null,
    geometryType: definition.geometryType,
    detailFields: getInheritedDetailFields(kind),
    externalLinks: getInheritedExternalLinks(kind).map((link) => ({
      label: link.label,
    })),
  }));
}

export function resolveFeatureStyle(kind, details = {}) {
  const { style } = getFeatureType(kind);
  return typeof style === "function" ? style(details) : { ...style };
}

export function resolveFeatureLinks(kind, details = {}) {
  return getInheritedExternalLinks(kind)
    .map((link) => ({
      label: link.label,
      url: link.url(details),
    }))
    .filter((link) => link.url);
}

function getFeatureTypeLineage(kind) {
  const lineage = [];
  let currentKind = kind;

  while (currentKind) {
    const definition = getFeatureType(currentKind);
    lineage.unshift(definition);
    currentKind = definition.parentKind;
  }

  return lineage;
}

function getInheritedDetailFields(kind) {
  return Object.assign(
    {},
    ...getFeatureTypeLineage(kind).map((definition) => definition.detailFields ?? {}),
  );
}

function getInheritedExternalLinks(kind) {
  return getFeatureTypeLineage(kind).flatMap((definition) => definition.externalLinks ?? []);
}
