import { JsonCleaner } from "../utils/jsonCleaner";
import { get, post } from "./serviceHelper";
export const TEMPLATE_BUILDER_AGENT_PROFILE_ID = "6f7a5e6e-0b6d-4f2d-bcc0-8b8bc3ef5374";
export const TEMPLATE_BUILDER_AGENT_PROFILE_NAME = "Template Builder";
export const TEMPLATE_BUILDER_SUGGESTION_SCHEMA_DESCRIPTION = `When you propose pending template changes, include exactly one fenced \`\`\`json code block containing an object with this shape:
{
  "summary": "Short summary of the suggestion set",
  "rationale": "Optional brief rationale",
  "baseTemplates": [
    {
      "action": "add | remove",
      "templateId": "optional Sitecore GUID",
      "templateName": "Template name",
      "templatePath": "optional Sitecore path",
      "reason": "optional"
    }
  ],
  "sections": [
    {
      "action": "add",
      "section": {
        "name": "Section name",
        "fields": [{ "name": "Field name", "type": "Single-Line Text" }]
      },
      "reason": "optional"
    },
    {
      "action": "update",
      "targetSectionName": "Existing section name",
      "section": { "name": "New section name" },
      "reason": "optional"
    },
    {
      "action": "remove",
      "targetSectionName": "Existing section name",
      "reason": "optional"
    }
  ],
  "fields": [
    {
      "action": "add",
      "targetSectionName": "Existing section name",
      "field": { "name": "Field name", "type": "Single-Line Text" },
      "reason": "optional"
    },
    {
      "action": "update",
      "targetSectionName": "Existing section name",
      "targetFieldName": "Existing field name",
      "field": { "name": "Optional new name", "type": "Optional new type" },
      "reason": "optional"
    },
    {
      "action": "remove",
      "targetSectionName": "Existing section name",
      "targetFieldName": "Existing field name",
      "reason": "optional"
    }
  ]
}

You may also include normal explanatory text outside the json block. Only the JSON block is treated as pending changes.`;
function asTrimmedString(value) {
    if (typeof value !== "string")
        return undefined;
    const trimmed = value.trim();
    return trimmed ? trimmed : undefined;
}
function asBoolean(value) {
    return typeof value === "boolean" ? value : undefined;
}
function normalizeFieldRequest(value, requireIdentity) {
    if (!value || typeof value !== "object" || Array.isArray(value))
        return null;
    const field = value;
    const normalized = {
        name: asTrimmedString(field.name),
        type: asTrimmedString(field.type),
        source: asTrimmedString(field.source),
        shared: asBoolean(field.shared),
        unversioned: asBoolean(field.unversioned),
        validation: asTrimmedString(field.validation),
        title: asTrimmedString(field.title),
        shortDescription: asTrimmedString(field.shortDescription),
        sortOrder: asTrimmedString(field.sortOrder),
        defaultValue: asTrimmedString(field.defaultValue),
    };
    const hasAnyValue = Object.values(normalized).some((entry) => entry !== undefined);
    if (!hasAnyValue)
        return null;
    if (requireIdentity && (!normalized.name || !normalized.type))
        return null;
    return normalized;
}
function normalizeSectionRequest(value, requireIdentity) {
    if (!value || typeof value !== "object" || Array.isArray(value))
        return null;
    const section = value;
    const name = asTrimmedString(section.name);
    const rawFields = Array.isArray(section.fields) ? section.fields : undefined;
    const fields = rawFields
        ?.map((field) => normalizeFieldRequest(field, true))
        .filter(Boolean);
    if (requireIdentity && !name)
        return null;
    if (!name && !fields?.length)
        return null;
    return {
        ...(name ? { name } : {}),
        ...(fields ? { fields } : {}),
    };
}
function isNonNullable(value) {
    return value != null;
}
function extractJsonObject(text) {
    const fencedMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
    if (fencedMatch?.[1]) {
        return fencedMatch[1].trim();
    }
    const trimmed = text.trim();
    if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
        return trimmed;
    }
    return null;
}
export function parseTemplateBuilderSuggestionText(text) {
    const jsonText = extractJsonObject(text);
    if (!jsonText)
        return null;
    const cleaned = JsonCleaner.cleanupJson(jsonText).cleanedJson;
    const parsed = JSON.parse(cleaned);
    const baseTemplates = Array.isArray(parsed.baseTemplates)
        ? parsed.baseTemplates
            .map((entry) => {
            if (!entry || typeof entry !== "object" || Array.isArray(entry))
                return null;
            const item = entry;
            const action = asTrimmedString(item.action);
            const templateName = asTrimmedString(item.templateName);
            if ((action !== "add" && action !== "remove") || !templateName) {
                return null;
            }
            return {
                action,
                templateId: asTrimmedString(item.templateId),
                templateName,
                templatePath: asTrimmedString(item.templatePath),
                reason: asTrimmedString(item.reason),
            };
        })
            .filter(isNonNullable)
        : [];
    const sections = Array.isArray(parsed.sections)
        ? parsed.sections
            .map((entry) => {
            if (!entry || typeof entry !== "object" || Array.isArray(entry))
                return null;
            const item = entry;
            const action = asTrimmedString(item.action);
            if (action === "add") {
                const section = normalizeSectionRequest(item.section, true);
                if (!section || !("name" in section) || !section.name)
                    return null;
                return {
                    action,
                    section: {
                        name: section.name,
                        fields: section.fields ?? [],
                    },
                    reason: asTrimmedString(item.reason),
                };
            }
            if (action === "update") {
                const targetSectionName = asTrimmedString(item.targetSectionName);
                const section = normalizeSectionRequest(item.section, false);
                if (!targetSectionName || !section)
                    return null;
                return {
                    action,
                    targetSectionName,
                    section,
                    reason: asTrimmedString(item.reason),
                };
            }
            if (action === "remove") {
                const targetSectionName = asTrimmedString(item.targetSectionName);
                if (!targetSectionName)
                    return null;
                return {
                    action,
                    targetSectionName,
                    reason: asTrimmedString(item.reason),
                };
            }
            return null;
        })
            .filter(isNonNullable)
        : [];
    const fields = Array.isArray(parsed.fields)
        ? parsed.fields
            .map((entry) => {
            if (!entry || typeof entry !== "object" || Array.isArray(entry))
                return null;
            const item = entry;
            const action = asTrimmedString(item.action);
            const targetSectionName = asTrimmedString(item.targetSectionName);
            if (!targetSectionName)
                return null;
            if (action === "add") {
                const field = normalizeFieldRequest(item.field, true);
                if (!field || !("name" in field) || !field.name || !field.type)
                    return null;
                return {
                    action,
                    targetSectionName,
                    field: field,
                    reason: asTrimmedString(item.reason),
                };
            }
            if (action === "update") {
                const targetFieldName = asTrimmedString(item.targetFieldName);
                const field = normalizeFieldRequest(item.field, false);
                if (!targetFieldName || !field)
                    return null;
                return {
                    action,
                    targetSectionName,
                    targetFieldName,
                    field,
                    reason: asTrimmedString(item.reason),
                };
            }
            if (action === "remove") {
                const targetFieldName = asTrimmedString(item.targetFieldName);
                if (!targetFieldName)
                    return null;
                return {
                    action,
                    targetSectionName,
                    targetFieldName,
                    reason: asTrimmedString(item.reason),
                };
            }
            return null;
        })
            .filter(isNonNullable)
        : [];
    const suggestion = {
        summary: asTrimmedString(parsed.summary),
        rationale: asTrimmedString(parsed.rationale),
        baseTemplates,
        sections,
        fields,
    };
    const hasChanges = baseTemplates.length > 0 || sections.length > 0 || fields.length > 0;
    return hasChanges || suggestion.summary || suggestion.rationale
        ? suggestion
        : null;
}
export async function templateBuilderPreflight(request) {
    return post("/parhelia/templateBuilderPreflight", request);
}
export async function templateBuilderCreate(request) {
    return post("/parhelia/templateBuilderCreate", request);
}
export async function templateBuilderGet(request) {
    return post("/parhelia/templateBuilderGet", request);
}
export async function templateBuilderUpdate(request) {
    return post("/parhelia/templateBuilderUpdate", request);
}
export async function templateBuilderFieldTypes() {
    const response = await fetch("/parhelia/templateBuilderFieldTypes", {
        method: "GET",
        credentials: "include",
        headers: {
            "Content-Type": "application/json",
        },
    });
    if (!response.ok)
        return [];
    const data = await response.json();
    return Array.isArray(data)
        ? data.filter((x) => x && typeof x.name === "string" && Array.isArray(x.types))
        : [];
}
export async function templateBuilderSkills() {
    const response = await get("/parhelia/templateBuilderSkills");
    if (response.type !== "success" || !Array.isArray(response.data))
        return [];
    return response.data.filter((x) => !!x && typeof x.id === "string" && typeof x.name === "string");
}
//# sourceMappingURL=templateBuilderService.js.map