use eidos_kernel::schema::Node;

use super::super::schema_profile::aun_frontmatter_profile;
use super::model::*;

pub(crate) fn is_trusted_relation(relation: &str) -> bool {
    use eidos_kernel::schema::relation::{MENTIONS, REFERENCES};
    relation != MENTIONS && relation != REFERENCES
}

pub(crate) fn source_for(node: &Node) -> Option<String> {
    node.source_files.first().cloned()
}

pub(crate) fn suggested_action(
    kind: &QualityFindingKind,
    field: Option<&str>,
    target: Option<&str>,
) -> Option<String> {
    match kind {
        QualityFindingKind::MalformedFrontmatter => {
            Some("Close the frontmatter block with a terminating `---` fence.".into())
        }
        QualityFindingKind::FrontmatterScalarListField => field
            .map(|field| format!("Rewrite `{field}` as a YAML list, keeping one value per item.")),
        QualityFindingKind::EmptyListItem => field
            .map(|field| format!("Remove empty entries from the `{field}` frontmatter list.")),
        QualityFindingKind::InvalidStatus => Some(
            "Set `status` to one of: active, draft, archived, deprecated.".into(),
        ),
        QualityFindingKind::UnknownType => field.map(|field| {
            format!("Replace `{field}` with a known Aun kind or remove it to use the default.")
        }),
        QualityFindingKind::TypeNormalized => field.map(|field| {
            format!("Use the normalized native `{field}` value in frontmatter.")
        }),
        QualityFindingKind::ConflictingTypeKind => {
            Some("Make `type` and `kind` agree, or keep only `type`.".into())
        }
        QualityFindingKind::UnknownFrontmatterField => field.map(|field| {
            format!("Rename or remove `{field}`; Aun does not read this frontmatter field.")
        }),
        QualityFindingKind::AuthoredRuntimeTruth => field.map(|field| {
            format!(
                "Remove `{field}`; Eidos computes it. Source files declare identity and intent, \
                 never runtime truth (tier/confidence/score/span/freshness)."
            )
        }),
        QualityFindingKind::TypeKindMissing => {
            Some("Add `type` or `kind` when the document has a stable Eidos role.".into())
        }
        QualityFindingKind::UnresolvedWikilink => target.map(|target| {
            format!("Create a node titled `{target}` or update the wikilink to an existing title, id, or alias.")
        }),
        QualityFindingKind::BrokenInternalMarkdownLink | QualityFindingKind::BrokenIndexLink => {
            target.map(|target| {
                format!("Create `{target}` or update the Markdown link to an existing markdown file.")
            })
        }
        QualityFindingKind::MalformedInternalMarkdownLink => {
            Some("Rewrite the Markdown link with a non-empty internal `.md` target.".into())
        }
        QualityFindingKind::MissingIndex => {
            Some("Add an `index.md` overview when this directory needs a navigation entry.".into())
        }
        QualityFindingKind::EmptyIndex => {
            Some("Add a short directory overview or links to important child markdown files.".into())
        }
        QualityFindingKind::MalformedLogDateHeading => {
            Some("Use dated log headings such as `## 2026-06-18`.".into())
        }
        QualityFindingKind::DuplicatePathIdentity => {
            Some(
                "No action is needed when one markdown file emits a document plus section nodes; investigate only if unrelated nodes share the same source path."
                    .into(),
            )
        }
        QualityFindingKind::UnresolvedFrontmatterTarget => {
            let field = field.unwrap_or("relation");
            target.map(|target| {
                format!("Create a node for `{target}` or update `{field}` to an existing title, id, or alias.")
            })
        }
        QualityFindingKind::OrphanNode => {
            Some("Link to this node from another trusted Aun doc or relation.".into())
        }
        QualityFindingKind::IsolatedNode => {
            Some("Add a trusted link/relation to or from each isolated node (see target for ids).".into())
        }
        QualityFindingKind::DuplicateTitle => {
            Some("Rename one duplicate title so each title slug is unique.".into())
        }
        QualityFindingKind::DuplicateAlias => target.map(|target| {
            format!("Make alias `{target}` unique, or remove it from nodes where it is not canonical.")
        }),
        QualityFindingKind::AliasDuplicatesTitle => target.map(|target| {
            format!("Remove alias `{target}` or rename it so it does not shadow a node title.")
        }),
        QualityFindingKind::DuplicateQueryExample => target.map(|target| {
            format!(
                "Keep query example `{target}` only on the canonical node, or rewrite it so each node owns distinct user language."
            )
        }),
        QualityFindingKind::QueryExampleDuplicatesTitle => target.map(|target| {
            format!(
                "Remove query example `{target}` or rewrite it so it does not shadow another node title."
            )
        }),
        QualityFindingKind::TitleMissing => {
            Some("Add a non-empty `title` frontmatter field, or `name` for a skill.".into())
        }
        QualityFindingKind::SummaryMissing => {
            Some("Add a non-empty `summary` frontmatter field.".into())
        }
        QualityFindingKind::NoSearchableBody => {
            Some("Add non-empty markdown body text or deterministic query_examples.".into())
        }
        QualityFindingKind::WeakDoc => {
            Some("Add a summary, description, or a non-heading body sentence.".into())
        }
    }
}

pub(crate) fn suggested_replacement(
    kind: &QualityFindingKind,
    _field: Option<&str>,
    target: Option<&str>,
) -> Option<String> {
    let profile = aun_frontmatter_profile();
    match kind {
        QualityFindingKind::InvalidStatus => target.and_then(|target| {
            let normalized = profile.normalize_status(target)?;
            (normalized != target).then_some(normalized)
        }),
        QualityFindingKind::TypeNormalized => target.and_then(|target| {
            let normalized = profile.normalize_kind(target)?;
            (normalized != target).then_some(normalized)
        }),
        _ => None,
    }
}

pub(crate) fn repair_metadata(
    kind: &QualityFindingKind,
    source: Option<&str>,
    field: Option<&str>,
    target: Option<&str>,
    suggested_action: Option<&str>,
    suggested_replacement: Option<&str>,
) -> (Repairability, Option<String>) {
    match kind {
        QualityFindingKind::InvalidStatus | QualityFindingKind::TypeNormalized
            if source.is_some()
                && suggested_replacement.is_some()
                && matches!(field, Some("status" | "type" | "kind")) =>
        {
            (
                Repairability::AutoProposable,
                Some("vyre_propose_frontmatter_fix".into()),
            )
        }
        QualityFindingKind::UnresolvedWikilink
        | QualityFindingKind::UnresolvedFrontmatterTarget
        | QualityFindingKind::MalformedFrontmatter
        | QualityFindingKind::FrontmatterScalarListField
        | QualityFindingKind::EmptyListItem
        | QualityFindingKind::InvalidStatus
        | QualityFindingKind::UnknownType
        | QualityFindingKind::ConflictingTypeKind
        | QualityFindingKind::UnknownFrontmatterField
        | QualityFindingKind::AuthoredRuntimeTruth
        | QualityFindingKind::TypeKindMissing
        | QualityFindingKind::OrphanNode
        | QualityFindingKind::IsolatedNode
        | QualityFindingKind::DuplicateTitle
        | QualityFindingKind::DuplicateAlias
        | QualityFindingKind::AliasDuplicatesTitle
        | QualityFindingKind::DuplicateQueryExample
        | QualityFindingKind::QueryExampleDuplicatesTitle
        | QualityFindingKind::TitleMissing
        | QualityFindingKind::SummaryMissing
        | QualityFindingKind::NoSearchableBody
        | QualityFindingKind::WeakDoc
        | QualityFindingKind::BrokenInternalMarkdownLink
        | QualityFindingKind::MalformedInternalMarkdownLink
        | QualityFindingKind::MissingIndex
        | QualityFindingKind::EmptyIndex
        | QualityFindingKind::BrokenIndexLink
        | QualityFindingKind::MalformedLogDateHeading
        | QualityFindingKind::DuplicatePathIdentity
            if suggested_action.is_some() || target.is_some() =>
        {
            (Repairability::Advisory, None)
        }
        _ => (Repairability::None, None),
    }
}
