use std::{str::FromStr, sync::LazyLock};

use crate::library::collection::{
    Collection, CollectionId, CollectionType, DynamicCollectionRules,
    rules::{GroupOp, RuleGroup, TrackRule},
};

pub const STATIC_COLLECTIONS_VERSION: u32 = 4;

pub static STATIC_COLLECTIONS: LazyLock<Box<[&'static Collection]>> = LazyLock::new(|| {
    Box::new([
        &COLLECTION_ALL,
        &COLLECTION_ALL_TRACKS,
        &COLLECTION_ALL_SINGLES,
        &COLLECTION_ALL_ALBUMS,
        &COLLECTION_INSTRUMENTAL,
        &COLLECTION_VOCAL,
        &COLLECTION_SYNCED_VOCAL,
    ])
});

static COLLECTION_ALL: LazyLock<Collection> = LazyLock::new(|| {
    const NAME: &str = "all";
    let id = CollectionId::from_str(NAME).unwrap();

    Collection {
        id,
        name: NAME.to_owned(),
        cover_art: None,
        items: CollectionType::Dynamic {
            rules: vec![
                DynamicCollectionRules::Album(RuleGroup::new()),
                DynamicCollectionRules::Track(RuleGroup {
                    rules: vec![TrackRule::Single],
                    op: GroupOp::Any,
                }),
            ],
        },
        read_only: true,
    }
});

static COLLECTION_ALL_TRACKS: LazyLock<Collection> = LazyLock::new(|| {
    const NAME: &str = "all-tracks";
    let id = CollectionId::from_str(NAME).unwrap();
    Collection {
        id,
        name: NAME.to_owned(),
        cover_art: None,
        items: CollectionType::Dynamic {
            rules: vec![DynamicCollectionRules::Track(RuleGroup::new())],
        },
        read_only: true,
    }
});

static COLLECTION_ALL_SINGLES: LazyLock<Collection> = LazyLock::new(|| {
    const NAME: &str = "all-singles";
    let id = CollectionId::from_str(NAME).unwrap();

    Collection {
        id,
        name: NAME.to_owned(),
        cover_art: None,
        items: CollectionType::Dynamic {
            rules: vec![DynamicCollectionRules::Track(RuleGroup {
                rules: vec![TrackRule::Single],
                op: GroupOp::Any,
            })],
        },
        read_only: true,
    }
});

static COLLECTION_ALL_ALBUMS: LazyLock<Collection> = LazyLock::new(|| {
    const NAME: &str = "all-albums";
    let id = CollectionId::from_str(NAME).unwrap();

    Collection {
        id,
        name: NAME.to_owned(),
        cover_art: None,
        items: CollectionType::Dynamic {
            rules: vec![DynamicCollectionRules::Album(RuleGroup::new())],
        },
        read_only: true,
    }
});

static COLLECTION_INSTRUMENTAL: LazyLock<Collection> = LazyLock::new(|| {
    const NAME: &str = "instrumental";
    let id = CollectionId::from_str(NAME).unwrap();

    Collection {
        id,
        name: NAME.to_owned(),
        cover_art: None,
        items: CollectionType::Dynamic {
            rules: vec![DynamicCollectionRules::Track(RuleGroup {
                rules: vec![TrackRule::Instrumental],
                op: GroupOp::Any,
            })],
        },
        read_only: true,
    }
});

static COLLECTION_VOCAL: LazyLock<Collection> = LazyLock::new(|| {
    const NAME: &str = "vocal";
    let id = CollectionId::from_str(NAME).unwrap();

    Collection {
        id,
        name: NAME.to_owned(),
        cover_art: None,
        items: CollectionType::Dynamic {
            rules: vec![DynamicCollectionRules::Track(RuleGroup {
                rules: vec![TrackRule::HasLyrics],
                op: GroupOp::Any,
            })],
        },
        read_only: true,
    }
});

static COLLECTION_SYNCED_VOCAL: LazyLock<Collection> = LazyLock::new(|| {
    const NAME: &str = "synced-vocal";
    let id = CollectionId::from_str(NAME).unwrap();

    Collection {
        id,
        name: NAME.to_owned(),
        cover_art: None,
        items: CollectionType::Dynamic {
            rules: vec![DynamicCollectionRules::Track(RuleGroup {
                rules: vec![TrackRule::HasSyncedLyrics],
                op: GroupOp::Any,
            })],
        },
        read_only: true,
    }
});
