export type PolicySourcePathItem = string | {
  scope_type?: string;
  scope_id?: string | null;
  path?: string;
  label: string;
  applied_fields?: string[];
  appliedFields?: string[];
  policy?: Record<string, unknown> | null;
};

export type PolicySourcePathProps = {
  items: PolicySourcePathItem[];
  label?: string;
  className?: string;
};

type NormalizedPolicySourcePathItem = {
  label: string;
  path?: string;
  appliedFields: string[];
  policy?: Record<string, unknown> | null;
};

export default function PolicySourcePath({ items, label = "i18n:govoplan-core.source_path.5956aebe", className = "" }: PolicySourcePathProps) {
  const cleanItems = items.map(normalizeSourceItem).filter((item): item is NormalizedPolicySourcePathItem => Boolean(item?.label));
  if (cleanItems.length === 0) return null;

  return (
    <div className={`policy-source-path ${className}`.trim()} aria-label={label}>
      <span className="policy-source-path-label">{label}</span>
      <ol>
        {cleanItems.map((item, index) =>
        <li key={`${item.label}-${index}`}>
            <span title={item.path}>{item.label}</span>
            {item.appliedFields.length > 0 && <small title={sourceFieldSummary(item.appliedFields, item.policy)}>{sourceFieldSummary(item.appliedFields, item.policy)}</small>}
          </li>
        )}
      </ol>
    </div>);

}

function normalizeSourceItem(item: PolicySourcePathItem): NormalizedPolicySourcePathItem | null {
  if (typeof item === "string") {
    const label = item.trim();
    return label ? { label, appliedFields: [] } : null;
  }
  const label = item.label?.trim();
  if (!label) return null;
  const appliedFields = [...(item.applied_fields ?? item.appliedFields ?? [])].map((field) => field.trim()).filter(Boolean);
  return { label, path: item.path, appliedFields, policy: item.policy };
}

function sourceFieldSummary(fields: string[], policy?: Record<string, unknown> | null): string {
  const unique = Array.from(new Set(fields));
  if (unique.length === 0) return "";
  if (unique.length === 1 && unique[0] === "defaults") return "defaults";
  if (unique.length <= 3) return unique.map((field) => sourceFieldDetail(field, policy)).join(", ");
  return `${unique.slice(0, 2).map(sourceFieldLabel).join(", ")} +${unique.length - 2}`;
}

function sourceFieldDetail(field: string, policy?: Record<string, unknown> | null): string {
  const value = readPolicyField(policy, field);
  const label = sourceFieldLabel(field);
  if (value === undefined) return label;
  if (typeof value === "boolean") return `${label}: ${value ? "allow" : "deny"}`;
  if (typeof value === "number" || typeof value === "string") return `${label}: ${value}`;
  if (value === null) return `${label}: none`;
  if (Array.isArray(value)) return `${label}: ${value.length}`;
  if (typeof value === "object") {
    const locked = Object.values(value as Record<string, unknown>).filter((item) => item === false).length;
    return locked > 0 ? `${label}: ${locked} locked` : label;
  }
  return label;
}

function readPolicyField(policy: Record<string, unknown> | null | undefined, field: string): unknown {
  if (!policy) return undefined;
  return field.split(".").reduce<unknown>((current, segment) => {
    if (!current || typeof current !== "object" || Array.isArray(current)) return undefined;
    return (current as Record<string, unknown>)[segment];
  }, policy);
}

function sourceFieldLabel(field: string): string {
  if (field === "defaults") return "defaults";
  const clean = field.
  replace(/^whitelist[.]/, "allow ").
  replace(/^blacklist[.]/, "block ").
  replace(/[_.]/g, " ").
  trim();
  return clean.charAt(0).toUpperCase() + clean.slice(1);
}
