use mad_hatter::Parseable;
use mad_hatter::llm::Parseable as _;
use mad_hatter::llm::Promptable as _;

#[derive(Parseable, Debug)]
enum TestVecAction {
    /// @render batch operation
    BatchOp {
        /// @render operation name
        name: String,
        /// @render target list
        targets: Vec<String>,
    },

    /// @render simple action
    SimpleAction,
}

#[derive(Parseable, Debug)]
struct TestVecStruct {
    /// @render title
    title: String,
    /// @render tag list
    tags: Vec<String>,
}

#[test]
fn test_enum_vec_string_schema() {
    let schema = TestVecAction::schema_markdown("tk1");
    // Vec<String> should use "each line is a string value" format
    assert!(
        schema.contains("targets-tk1"),
        "schema should contain targets field separator, got: {}",
        schema
    );
}

#[test]
fn test_enum_vec_string_parse() {
    let token = "tk1";
    let input = format!(
        "TestVecAction-{t}\nbatch_op\nname-{t}\nmy-operation\ntargets-{t}\nalpha\nbeta\ngamma\nTestVecAction-end-{t}",
        t = token
    );
    let results = TestVecAction::from_markdown(&input, token);
    assert!(results.is_ok(), "parse should succeed, got: {:?}", results);
    let items = results.unwrap();
    assert_eq!(items.len(), 1, "should parse one action");
    match &items[0] {
        TestVecAction::BatchOp { name, targets } => {
            assert_eq!(name, "my-operation");
            assert_eq!(targets, &vec!["alpha".to_string(), "beta".to_string(), "gamma".to_string()]);
        }
        _ => panic!("expected BatchOp variant"),
    }
}

#[test]
fn test_enum_vec_string_parse_with_comments() {
    let token = "tk2";
    let input = format!(
        "TestVecAction-{t}\nbatch_op\nname-{t}\ntest-op\ntargets-{t}\n// this is a comment\nfoo\n\nbar\nTestVecAction-end-{t}",
        t = token
    );
    let results = TestVecAction::from_markdown(&input, token);
    assert!(results.is_ok(), "parse should succeed, got: {:?}", results);
    let items = results.unwrap();
    assert_eq!(items.len(), 1);
    match &items[0] {
        TestVecAction::BatchOp { name, targets } => {
            assert_eq!(name, "test-op");
            // Comments and empty lines should be filtered out
            assert_eq!(targets, &vec!["foo".to_string(), "bar".to_string()]);
        }
        _ => panic!("expected BatchOp variant"),
    }
}

#[test]
fn test_enum_vec_string_empty() {
    let token = "tk3";
    let input = format!(
        "TestVecAction-{t}\nbatch_op\nname-{t}\nempty-op\ntargets-{t}\nTestVecAction-end-{t}",
        t = token
    );
    let results = TestVecAction::from_markdown(&input, token);
    assert!(results.is_ok(), "parse should succeed, got: {:?}", results);
    let items = results.unwrap();
    assert_eq!(items.len(), 1);
    match &items[0] {
        TestVecAction::BatchOp { name, targets } => {
            assert_eq!(name, "empty-op");
            assert!(targets.is_empty(), "targets should be empty");
        }
        _ => panic!("expected BatchOp variant"),
    }
}

#[test]
fn test_struct_vec_string_schema() {
    let schema = TestVecStruct::schema_markdown("tk4");
    assert!(
        schema.contains("tags-tk4"),
        "schema should contain tags field separator, got: {}",
        schema
    );
}

#[test]
fn test_struct_vec_string_parse() {
    let token = "tk5";
    let input = format!(
        "TestVecStruct-{t}\ntitle-{t}\nmy-title\ntags-{t}\ntag1\ntag2\ntag3\nTestVecStruct-end-{t}",
        t = token
    );
    let results = TestVecStruct::from_markdown(&input, token);
    assert!(results.is_ok(), "parse should succeed, got: {:?}", results);
    let items = results.unwrap();
    assert_eq!(items.len(), 1);
    assert_eq!(items[0].title, "my-title");
    assert_eq!(items[0].tags, vec!["tag1".to_string(), "tag2".to_string(), "tag3".to_string()]);
}