use std::collections::{HashMap, HashSet};

use fluent_bundle::FluentResource;
use fluent_syntax::ast::{Expression, InlineExpression, Pattern, PatternElement};
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::ext::IdentExt;

use crate::diagnostics::error::span_err;
use crate::diagnostics::utils::FieldMap;

#[derive(Clone)]
pub(crate) struct Message {
    pub attr_span: Span,
    pub message_span: Span,
    pub value: String,
}

impl Message {
    // About `allow(rustc::potential_query_instability)`: The order of key/values of `fields` and
    // `field_map` doesn't matters.
    #[allow(rustc::potential_query_instability)]
    pub(crate) fn new(
        attr_span: Span,
        message_span: Span,
        message_str: String,
        field_map: &FieldMap,
        used_fields: &mut HashSet<proc_macro2::Ident>,
    ) -> Self {
        // Parse the fluent message
        const GENERATED_MSG_ID: &str = "generated_msg";
        let resource =
            FluentResource::try_new(format!("{GENERATED_MSG_ID} = {message_str}\n")).unwrap();
        assert_eq!(resource.entries().count(), 1);
        let Some(fluent_syntax::ast::Entry::Message(flt_message)) = resource.get_entry(0) else {
            panic!("Did not parse into a message")
        };

        let mut fields: HashMap<String, (&syn::Ident, bool)> =
            HashMap::with_capacity(field_map.len());
        for (_, (ident, _)) in field_map {
            fields.insert(ident.unraw().to_string(), (ident, false));
        }
        for variable in variable_references(&flt_message) {
            match fields.get_mut(variable) {
                Some((_, seen)) => *seen = true,
                None => {
                    span_err(
                        message_span.unwrap(),
                        format!("Variable `{variable}` not found in diagnostic "),
                    )
                    .help(format!(
                        "Available fields: {:?}",
                        fields.keys().map(|s| s.as_str()).collect::<Vec<&str>>().join(", ")
                    ))
                    .emit();
                }
            }
        }
        for (name, seen) in fields.values() {
            if *seen {
                used_fields.insert((*name).clone());
            }
        }
        Self { attr_span, message_span, value: message_str }
    }

    /// Get the diagnostic message for this diagnostic
    /// The passed `variant` is used to check whether all variables in the message are used.
    /// For subdiagnostics, we cannot check this.
    pub(crate) fn diag_message(&self) -> TokenStream {
        let message = &self.value;
        self.verify();
        quote! { rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed(#message)) }
    }

    fn verify(&self) {
        verify_message_style(self.message_span, &self.value);
        verify_message_formatting(self.attr_span, self.message_span, &self.value);
    }
}

fn variable_references<'a>(msg: &fluent_syntax::ast::Message<&'a str>) -> Vec<&'a str> {
    let mut refs = vec![];

    if let Some(Pattern { elements }) = &msg.value {
        for elt in elements {
            traverse_pattern(elt, &mut refs);
        }
    }
    for attr in &msg.attributes {
        for elt in &attr.value.elements {
            traverse_pattern(elt, &mut refs);
        }
    }

    fn traverse_pattern<'a>(elem: &PatternElement<&'a str>, refs: &mut Vec<&'a str>) {
        match elem {
            PatternElement::TextElement { .. } => {}
            PatternElement::Placeable { expression } => traverse_expression(expression, refs),
        }
    }
    fn traverse_expression<'a>(expr: &Expression<&'a str>, refs: &mut Vec<&'a str>) {
        match expr {
            Expression::Select { selector, variants } => {
                traverse_inline_expr(selector, refs);
                for variant in variants {
                    for pattern in &variant.value.elements {
                        traverse_pattern(pattern, refs);
                    }
                }
            }
            Expression::Inline(expr) => {
                traverse_inline_expr(expr, refs);
            }
        }
    }
    fn traverse_inline_expr<'a>(elem: &InlineExpression<&'a str>, refs: &mut Vec<&'a str>) {
        match elem {
            InlineExpression::VariableReference { id } => refs.push(id.name),
            _ => {}
        }
    }

    refs
}

const ALLOWED_CAPITALIZED_WORDS: &[&str] = &[
    // tidy-alphabetical-start
    "ABI",
    "ABIs",
    "ADT",
    "C-variadic",
    "CGU-reuse",
    "Cargo",
    "Ferris",
    "GCC",
    "MIR",
    "NaNs",
    "OK",
    "Rust",
    "ThinLTO",
    "Unicode",
    "VS",
    // tidy-alphabetical-end
];

/// See: https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-output-style-guide
fn verify_message_style(msg_span: Span, message: &str) {
    // Verify that message starts with lowercase char
    let Some(first_word) = message.split_whitespace().next() else {
        span_err(msg_span.unwrap(), "message must not be empty").emit();
        return;
    };
    let first_char = first_word.chars().next().expect("Word is not empty");
    if first_char.is_uppercase() && !ALLOWED_CAPITALIZED_WORDS.contains(&first_word) {
        span_err(msg_span.unwrap(), "message `{value}` starts with an uppercase letter. Fix it or add it to `ALLOWED_CAPITALIZED_WORDS`").emit();
        return;
    }

    // Verify that message does not end in `.`
    if message.ends_with(".") && !message.ends_with("...") {
        span_err(msg_span.unwrap(), "message `{value}` ends with a period").emit();
        return;
    }
}

/// Verifies that the message is properly indented into the code
fn verify_message_formatting(attr_span: Span, msg_span: Span, message: &str) {
    // Find the indent at the start of the message (`column()` is one-indexed)
    let start = attr_span.unwrap().column() - 1;

    for line in message.lines().skip(1) {
        if line.is_empty() {
            continue;
        }
        let indent = line.chars().take_while(|c| *c == ' ').count();
        if indent < start {
            span_err(
                msg_span.unwrap(),
                format!("message is not properly indented. {indent} < {start}"),
            )
            .emit();
            return;
        }
        if indent % 4 != 0 {
            span_err(msg_span.unwrap(), "message is not indented with a multiple of 4 spaces")
                .emit();
            return;
        }
    }
}
