import type {
  ConformComponentMapping,
  DesignSystemContext,
  GovernanceConfig,
} from "@fragments-sdk/core";

export const COLOR_RULE_ID = "styles/no-raw-color";
export const DIMENSION_RULE_ID = "styles/no-raw-dimensions";
export const COMPONENT_RULE_ID = "components/prefer-library";
export const TOKEN_RULE_IDS = new Set([COLOR_RULE_ID, DIMENSION_RULE_ID]);

const DIMENSION_PROPERTIES = [
  "padding",
  "padding-top",
  "padding-right",
  "padding-bottom",
  "padding-left",
  "margin",
  "margin-top",
  "margin-right",
  "margin-bottom",
  "margin-left",
  "gap",
  "row-gap",
  "column-gap",
  "border-radius",
  "border-top-left-radius",
  "border-top-right-radius",
  "border-bottom-right-radius",
  "border-bottom-left-radius",
];

const CONFORM_POLICY: GovernanceConfig = {
  severity: "warn",
  rules: { "tokens/hardcoded-values": { enabled: true, severity: "warn" } },
  styles: [
    {
      kind: "style.rawColors.forbid",
      except: ["transparent", "currentColor", "inherit", "initial", "unset", "none"],
      prefer: "token",
      severity: "warn",
    },
    {
      kind: "style.rawDimensions.forbid",
      appliesTo: DIMENSION_PROPERTIES,
      prefer: "token",
      severity: "warn",
    },
  ],
};

export function buildConformPolicy(context: DesignSystemContext): GovernanceConfig {
  const componentMappings = (context.components ?? []).filter(isUsableComponentMapping);
  if (componentMappings.length === 0) return CONFORM_POLICY;
  return {
    ...CONFORM_POLICY,
    rules: {
      ...CONFORM_POLICY.rules,
      [COMPONENT_RULE_ID]: {
        enabled: true,
        severity: "warn",
        options: { canonicalMappings: componentMappings },
      },
    },
  };
}

export function isUsableComponentMapping(mapping: ConformComponentMapping): boolean {
  return Boolean(mapping.name && (mapping.htmlEquivalent || mapping.importPath));
}

/** Count the component mappings the engine can actually evaluate against. */
export function countUsableComponents(context: DesignSystemContext): number {
  return (context.components ?? []).filter(isUsableComponentMapping).length;
}
