use super::*;

impl SchemaValidator {
    pub(super) fn validate_composite_types(&mut self) {
        let types: Vec<_> = self.schema.types().cloned().collect();
        for type_decl in &types {
            self.validate_composite_type(type_decl);
        }
    }

    pub(super) fn validate_composite_type(&mut self, type_decl: &TypeDecl) {
        let mut field_names: HashMap<String, Span> = HashMap::new();
        for field in &type_decl.fields {
            let name = &field.name.value;
            if field_names.contains_key(name) {
                self.errors.push_back(SchemaError::Validation(
                    format!(
                        "Duplicate field name '{}' in type '{}'",
                        name, type_decl.name.value
                    ),
                    field.name.span,
                ));
            } else {
                field_names.insert(name.clone(), field.name.span);
            }

            if let FieldType::UserType(type_name) = &field.field_type {
                if self.models.contains_key(type_name) {
                    self.errors.push_back(SchemaError::Validation(
                        format!(
                            "Field '{}' in type '{}' cannot have a model type '{}'. Composite type fields must be scalar, enum, or array of scalars/enums.",
                            name, type_decl.name.value, type_name
                        ),
                        field.span,
                    ));
                } else if self.composite_types.contains_key(type_name) {
                    self.errors.push_back(SchemaError::Validation(
                        format!(
                            "Field '{}' in type '{}' cannot reference another composite type '{}'. Nested composite types are not supported.",
                            name, type_decl.name.value, type_name
                        ),
                        field.span,
                    ));
                } else if !self.enums.contains_key(type_name) {
                    self.errors.push_back(SchemaError::Validation(
                        format!(
                            "Unknown type '{}' for field '{}' in type '{}'",
                            type_name, name, type_decl.name.value
                        ),
                        field.span,
                    ));
                }
            }

            for attr in &field.attributes {
                match attr {
                    FieldAttribute::Map(_) | FieldAttribute::Store { .. } => {}
                    FieldAttribute::Id => {
                        self.errors.push_back(SchemaError::Validation(
                            format!(
                                "@id is not allowed on fields inside a composite type (field '{}' in type '{}')",
                                name, type_decl.name.value
                            ),
                            field.span,
                        ));
                    }
                    FieldAttribute::Unique => {
                        self.errors.push_back(SchemaError::Validation(
                            format!(
                                "@unique is not allowed on fields inside a composite type (field '{}' in type '{}')",
                                name, type_decl.name.value
                            ),
                            field.span,
                        ));
                    }
                    FieldAttribute::Relation { .. } => {
                        self.errors.push_back(SchemaError::Validation(
                            format!(
                                "@relation is not allowed on fields inside a composite type (field '{}' in type '{}')",
                                name, type_decl.name.value
                            ),
                            field.span,
                        ));
                    }
                    FieldAttribute::Computed { .. } => {
                        self.errors.push_back(SchemaError::Validation(
                            format!(
                                "@computed is not allowed on fields inside a composite type (field '{}' in type '{}')",
                                name, type_decl.name.value
                            ),
                            field.span,
                        ));
                    }
                    FieldAttribute::Check { .. } => {
                        self.errors.push_back(SchemaError::Validation(
                            format!(
                                "@check is not allowed on fields inside a composite type (field '{}' in type '{}')",
                                name, type_decl.name.value
                            ),
                            field.span,
                        ));
                    }
                    FieldAttribute::Default(_, _) => {
                        self.errors.push_back(SchemaError::Validation(
                            format!(
                                "@default is not allowed on fields inside a composite type (field '{}' in type '{}')",
                                name, type_decl.name.value
                            ),
                            field.span,
                        ));
                    }
                    FieldAttribute::UpdatedAt { .. } => {
                        self.errors.push_back(SchemaError::Validation(
                            format!(
                                "@updatedAt is not allowed on fields inside a composite type (field '{}' in type '{}')",
                                name, type_decl.name.value
                            ),
                            field.span,
                        ));
                    }
                }
            }
        }
    }
}
