use super::{pk_rust_type, pk_use_import, type_map, FieldDef};

pub fn gen(
    pascal: &str,
    _snake: &str,
    fields: &[FieldDef],
    id: Option<&str>,
    timestamps: bool,
    soft_delete: bool,
) -> String {
    let pk_type = pk_rust_type(id);
    let pk_use = pk_use_import(id);

    let id_fake = match id {
        None => "0_i64".to_string(),
        _ => format!("{}::default()", pk_type),
    };

    let mut field_defaults = format!("            id: {id_fake},\n");
    for f in fields {
        let val = if f.optional {
            "None".to_string()
        } else {
            let tm = type_map(&f.field_type);
            tm.fake_val.to_string()
        };
        field_defaults.push_str(&format!("            {}: {},\n", f.name, val));
    }
    if timestamps {
        field_defaults.push_str("            created_at: chrono::Utc::now(),\n");
        field_defaults.push_str("            updated_at: chrono::Utc::now(),\n");
    }
    if soft_delete {
        field_defaults.push_str("            deleted_at: None,\n");
    }

    let uses = pk_use.to_string();

    format!(
        "{uses}use crate::app::models::{pascal};\n\npub struct {pascal}Factory;\n\nimpl {pascal}Factory {{\n    pub fn build() -> {pascal} {{\n        {pascal} {{\n{field_defaults}        }}\n    }}\n}}\n"
    )
}
