use super::*;
use crate::gitlab::types::GitLabAuthor;

fn passes_cursor_filter(issue: &GitLabIssue, cursor: &SyncCursor) -> Result<bool> {
    let Some(cursor_ts) = cursor.updated_at_cursor else {
        return Ok(true);
    };

    let issue_ts = parse_timestamp(&issue.updated_at)?;

    if issue_ts < cursor_ts {
        return Ok(false);
    }

    if issue_ts == cursor_ts
        && cursor
            .tie_breaker_id
            .is_some_and(|cursor_id| issue.id <= cursor_id)
    {
        return Ok(false);
    }

    Ok(true)
}

fn make_test_issue(id: i64, updated_at: &str) -> GitLabIssue {
    GitLabIssue {
        id,
        iid: id,
        project_id: 100,
        title: format!("Issue {}", id),
        description: None,
        state: "opened".to_string(),
        created_at: "2024-01-01T00:00:00.000Z".to_string(),
        updated_at: updated_at.to_string(),
        closed_at: None,
        author: GitLabAuthor {
            id: 1,
            username: "test".to_string(),
            name: "Test".to_string(),
        },
        assignees: vec![],
        labels: vec![],
        milestone: None,
        due_date: None,
        web_url: "https://example.com".to_string(),
    }
}

#[test]
fn cursor_filter_allows_newer_issues() {
    let cursor = SyncCursor {
        updated_at_cursor: Some(1705312800000),
        tie_breaker_id: Some(100),
    };

    let issue = make_test_issue(101, "2024-01-16T10:00:00.000Z");
    assert!(passes_cursor_filter(&issue, &cursor).unwrap_or(false));
}

#[test]
fn cursor_filter_blocks_older_issues() {
    let cursor = SyncCursor {
        updated_at_cursor: Some(1705312800000),
        tie_breaker_id: Some(100),
    };

    let issue = make_test_issue(99, "2024-01-14T10:00:00.000Z");
    assert!(!passes_cursor_filter(&issue, &cursor).unwrap_or(true));
}

#[test]
fn cursor_filter_uses_tie_breaker_for_same_timestamp() {
    let cursor = SyncCursor {
        updated_at_cursor: Some(1705312800000),
        tie_breaker_id: Some(100),
    };

    let issue1 = make_test_issue(101, "2024-01-15T10:00:00.000Z");
    assert!(passes_cursor_filter(&issue1, &cursor).unwrap_or(false));

    let issue2 = make_test_issue(100, "2024-01-15T10:00:00.000Z");
    assert!(!passes_cursor_filter(&issue2, &cursor).unwrap_or(true));

    let issue3 = make_test_issue(99, "2024-01-15T10:00:00.000Z");
    assert!(!passes_cursor_filter(&issue3, &cursor).unwrap_or(true));
}

#[test]
fn cursor_filter_allows_all_when_no_cursor() {
    let cursor = SyncCursor::default();

    let issue = make_test_issue(1, "2020-01-01T00:00:00.000Z");
    assert!(passes_cursor_filter(&issue, &cursor).unwrap_or(false));
}
