use proc_macro2::TokenStream;
use quote::quote;
use syn::{punctuated::Punctuated, DeriveInput, Token};

use crate::code::Code;
use crate::diagnostic_arg::DiagnosticArg;
use crate::diagnostic_source::DiagnosticSource;
use crate::forward::{Forward, WhichFn};
use crate::help::Help;
use crate::label::Labels;
use crate::related::Related;
use crate::severity::Severity;
use crate::source_code::SourceCode;
use crate::url::Url;

pub enum Diagnostic {
    Struct {
        generics: syn::Generics,
        ident: syn::Ident,
        fields: syn::Fields,
        args: DiagnosticDefArgs,
    },
    Enum {
        ident: syn::Ident,
        generics: syn::Generics,
        variants: Vec<DiagnosticDef>,
    },
}

pub struct DiagnosticDef {
    pub ident: syn::Ident,
    pub fields: syn::Fields,
    pub args: DiagnosticDefArgs,
}

pub enum DiagnosticDefArgs {
    Transparent(Forward),
    Concrete(Box<DiagnosticConcreteArgs>),
}

impl DiagnosticDefArgs {
    pub(crate) fn forward_or_override_enum(
        &self,
        variant: &syn::Ident,
        which_fn: WhichFn,
        mut f: impl FnMut(&DiagnosticConcreteArgs) -> Option<TokenStream>,
    ) -> Option<TokenStream> {
        match self {
            Self::Transparent(forward) => Some(forward.gen_enum_match_arm(variant, which_fn)),
            Self::Concrete(concrete) => f(concrete).or_else(|| {
                concrete
                    .forward
                    .as_ref()
                    .map(|forward| forward.gen_enum_match_arm(variant, which_fn))
            }),
        }
    }
}

#[derive(Default)]
pub struct DiagnosticConcreteArgs {
    pub code: Option<Code>,
    pub severity: Option<Severity>,
    pub help: Option<Help>,
    pub labels: Option<Labels>,
    pub source_code: Option<SourceCode>,
    pub url: Option<Url>,
    pub forward: Option<Forward>,
    pub related: Option<Related>,
    pub diagnostic_source: Option<DiagnosticSource>,
}

impl DiagnosticConcreteArgs {
    fn for_fields(fields: &syn::Fields) -> Result<Self, syn::Error> {
        let labels = Labels::from_fields(fields)?;
        let source_code = SourceCode::from_fields(fields)?;
        let related = Related::from_fields(fields)?;
        let help = Help::from_fields(fields)?;
        let diagnostic_source = DiagnosticSource::from_fields(fields)?;
        Ok(DiagnosticConcreteArgs {
            code: None,
            help,
            related,
            severity: None,
            labels,
            url: None,
            forward: None,
            source_code,
            diagnostic_source,
        })
    }

    fn add_args(
        &mut self,
        attr: &syn::Attribute,
        args: impl Iterator<Item = DiagnosticArg>,
        errors: &mut Vec<syn::Error>,
    ) {
        for arg in args {
            match arg {
                DiagnosticArg::Transparent => {
                    errors.push(syn::Error::new_spanned(attr, "transparent not allowed"));
                }
                DiagnosticArg::Forward(to_field) => {
                    if self.forward.is_some() {
                        errors.push(syn::Error::new_spanned(
                            attr,
                            "forward has already been specified",
                        ));
                    }
                    self.forward = Some(to_field);
                }
                DiagnosticArg::Code(new_code) => {
                    if self.code.is_some() {
                        errors.push(syn::Error::new_spanned(
                            attr,
                            "code has already been specified",
                        ));
                    }
                    self.code = Some(new_code);
                }
                DiagnosticArg::Severity(sev) => {
                    if self.severity.is_some() {
                        errors.push(syn::Error::new_spanned(
                            attr,
                            "severity has already been specified",
                        ));
                    }
                    self.severity = Some(sev);
                }
                DiagnosticArg::Help(hl) => {
                    if self.help.is_some() {
                        errors.push(syn::Error::new_spanned(
                            attr,
                            "help has already been specified",
                        ));
                    }
                    self.help = Some(hl);
                }
                DiagnosticArg::Url(u) => {
                    if self.url.is_some() {
                        errors.push(syn::Error::new_spanned(
                            attr,
                            "url has already been specified",
                        ));
                    }
                    self.url = Some(u);
                }
            }
        }
    }
}

impl DiagnosticDefArgs {
    fn parse(
        _ident: &syn::Ident,
        fields: &syn::Fields,
        attrs: &[&syn::Attribute],
        allow_transparent: bool,
    ) -> syn::Result<Self> {
        let mut errors = Vec::new();

        // Handle the only condition where Transparent is allowed
        if allow_transparent && attrs.len() == 1 {
            if let Ok(args) =
                attrs[0].parse_args_with(Punctuated::<DiagnosticArg, Token![,]>::parse_terminated)
            {
                if matches!(args.first(), Some(DiagnosticArg::Transparent)) {
                    let forward = Forward::for_transparent_field(fields)?;
                    return Ok(Self::Transparent(forward));
                }
            }
        }

        // Create errors for any appearances of Transparent
        let error_message = if allow_transparent {
            "diagnostic(transparent) not allowed in combination with other args"
        } else {
            "diagnostic(transparent) not allowed here"
        };
        fn is_transparent(d: &DiagnosticArg) -> bool {
            matches!(d, DiagnosticArg::Transparent)
        }

        let mut concrete = DiagnosticConcreteArgs::for_fields(fields)?;
        for attr in attrs {
            let args =
                attr.parse_args_with(Punctuated::<DiagnosticArg, Token![,]>::parse_terminated);
            let args = match args {
                Ok(args) => args,
                Err(error) => {
                    errors.push(error);
                    continue;
                }
            };

            if args.iter().any(is_transparent) {
                errors.push(syn::Error::new_spanned(attr, error_message));
            }

            let args = args
                .into_iter()
                .filter(|x| !matches!(x, DiagnosticArg::Transparent));

            concrete.add_args(attr, args, &mut errors);
        }

        let combined_error = errors.into_iter().reduce(|mut lhs, rhs| {
            lhs.combine(rhs);
            lhs
        });
        if let Some(error) = combined_error {
            Err(error)
        } else {
            Ok(DiagnosticDefArgs::Concrete(Box::new(concrete)))
        }
    }
}

impl Diagnostic {
    pub fn from_derive_input(input: DeriveInput) -> Result<Self, syn::Error> {
        let input_attrs = input
            .attrs
            .iter()
            .filter(|x| x.path().is_ident("diagnostic"))
            .collect::<Vec<&syn::Attribute>>();
        Ok(match input.data {
            syn::Data::Struct(data_struct) => {
                let args = DiagnosticDefArgs::parse(
                    &input.ident,
                    &data_struct.fields,
                    &input_attrs,
                    true,
                )?;

                Diagnostic::Struct {
                    fields: data_struct.fields,
                    ident: input.ident,
                    generics: input.generics,
                    args,
                }
            }
            syn::Data::Enum(syn::DataEnum { variants, .. }) => {
                let mut vars = Vec::new();
                for var in variants {
                    let mut variant_attrs = input_attrs.clone();
                    variant_attrs
                        .extend(var.attrs.iter().filter(|x| x.path().is_ident("diagnostic")));
                    let args =
                        DiagnosticDefArgs::parse(&var.ident, &var.fields, &variant_attrs, true)?;
                    vars.push(DiagnosticDef {
                        ident: var.ident,
                        fields: var.fields,
                        args,
                    });
                }
                Diagnostic::Enum {
                    ident: input.ident,
                    generics: input.generics,
                    variants: vars,
                }
            }
            syn::Data::Union(_) => {
                return Err(syn::Error::new(
                    input.ident.span(),
                    "Can't derive Diagnostic for Unions",
                ))
            }
        })
    }

    pub fn gen(&self) -> TokenStream {
        match self {
            Self::Struct {
                ident,
                fields,
                generics,
                args,
            } => {
                let (impl_generics, ty_generics, where_clause) = &generics.split_for_impl();
                match args {
                    DiagnosticDefArgs::Transparent(forward) => {
                        let code_method = forward.gen_struct_method(WhichFn::Code);
                        let help_method = forward.gen_struct_method(WhichFn::Help);
                        let url_method = forward.gen_struct_method(WhichFn::Url);
                        let labels_method = forward.gen_struct_method(WhichFn::Labels);
                        let source_code_method = forward.gen_struct_method(WhichFn::SourceCode);
                        let severity_method = forward.gen_struct_method(WhichFn::Severity);
                        let related_method = forward.gen_struct_method(WhichFn::Related);
                        let diagnostic_source_method =
                            forward.gen_struct_method(WhichFn::DiagnosticSource);

                        quote! {
                            impl #impl_generics miette::Diagnostic for #ident #ty_generics #where_clause {
                                #code_method
                                #help_method
                                #url_method
                                #labels_method
                                #severity_method
                                #source_code_method
                                #related_method
                                #diagnostic_source_method
                            }
                        }
                    }
                    DiagnosticDefArgs::Concrete(concrete) => {
                        let forward = |which| {
                            concrete
                                .forward
                                .as_ref()
                                .map(|fwd| fwd.gen_struct_method(which))
                        };
                        let code_body = concrete
                            .code
                            .as_ref()
                            .and_then(|x| x.gen_struct())
                            .or_else(|| forward(WhichFn::Code));
                        let help_body = concrete
                            .help
                            .as_ref()
                            .and_then(|x| x.gen_struct(fields))
                            .or_else(|| forward(WhichFn::Help));
                        let sev_body = concrete
                            .severity
                            .as_ref()
                            .and_then(|x| x.gen_struct())
                            .or_else(|| forward(WhichFn::Severity));
                        let rel_body = concrete
                            .related
                            .as_ref()
                            .and_then(|x| x.gen_struct())
                            .or_else(|| forward(WhichFn::Related));
                        let url_body = concrete
                            .url
                            .as_ref()
                            .and_then(|x| x.gen_struct(ident, fields))
                            .or_else(|| forward(WhichFn::Url));
                        let labels_body = concrete
                            .labels
                            .as_ref()
                            .and_then(|x| x.gen_struct(fields))
                            .or_else(|| forward(WhichFn::Labels));
                        let src_body = concrete
                            .source_code
                            .as_ref()
                            .and_then(|x| x.gen_struct(fields))
                            .or_else(|| forward(WhichFn::SourceCode));
                        let diagnostic_source = concrete
                            .diagnostic_source
                            .as_ref()
                            .and_then(|x| x.gen_struct())
                            .or_else(|| forward(WhichFn::DiagnosticSource));
                        quote! {
                            impl #impl_generics miette::Diagnostic for #ident #ty_generics #where_clause {
                                #code_body
                                #help_body
                                #sev_body
                                #rel_body
                                #url_body
                                #labels_body
                                #src_body
                                #diagnostic_source
                            }
                        }
                    }
                }
            }
            Self::Enum {
                ident,
                generics,
                variants,
            } => {
                let (impl_generics, ty_generics, where_clause) = &generics.split_for_impl();
                let code_body = Code::gen_enum(variants);
                let help_body = Help::gen_enum(variants);
                let sev_body = Severity::gen_enum(variants);
                let labels_body = Labels::gen_enum(variants);
                let src_body = SourceCode::gen_enum(variants);
                let rel_body = Related::gen_enum(variants);
                let url_body = Url::gen_enum(ident, variants);
                let diagnostic_source_body = DiagnosticSource::gen_enum(variants);
                quote! {
                    impl #impl_generics miette::Diagnostic for #ident #ty_generics #where_clause {
                        #code_body
                        #help_body
                        #sev_body
                        #labels_body
                        #src_body
                        #rel_body
                        #url_body
                        #diagnostic_source_body
                    }
                }
            }
        }
    }
}
