use cosmwasm_schema::QueryResponses;
use cosmwasm_std::Addr;
use cw_asset::{AssetInfo, AssetInfoUnchecked};
use crate::objects::{
    pool_id::UncheckedPoolAddress, pool_reference::PoolReference, AssetEntry, ChannelEntry,
    ContractEntry, DexAssetPairing, PoolMetadata, PoolType, UncheckedChannelEntry,
    UncheckedContractEntry, UniquePoolId,
};
pub type AssetPair = (AssetEntry, AssetEntry);
type DexName = String;
pub type AssetPairingMapEntry = (DexAssetPairing, Vec<PoolReference>);
pub type AssetMapEntry = (AssetEntry, AssetInfo);
pub type AssetInfoMapEntry = (AssetInfo, AssetEntry);
pub type ChannelMapEntry = (ChannelEntry, String);
pub type ContractMapEntry = (ContractEntry, Addr);
pub type PoolMetadataMapEntry = (UniquePoolId, PoolMetadata);
pub mod state {
    use cosmwasm_std::Addr;
    use cw_asset::AssetInfo;
    use cw_storage_plus::{Item, Map};
    use crate::{
        ans_host::{DexAssetPairing, DexName, UniquePoolId},
        objects::{
            pool_metadata::PoolMetadata, pool_reference::PoolReference, AssetEntry, ChannelEntry,
            ContractEntry,
        },
    };
    #[cosmwasm_schema::cw_serde]
    pub struct Config {
        pub next_unique_pool_id: UniquePoolId,
    }
    pub const CONFIG: Item<Config> = Item::new("config");
    pub const ASSET_ADDRESSES: Map<&AssetEntry, AssetInfo> = Map::new("assets");
    pub const REV_ASSET_ADDRESSES: Map<&AssetInfo, AssetEntry> = Map::new("rev_assets");
    pub const CONTRACT_ADDRESSES: Map<&ContractEntry, Addr> = Map::new("contracts");
    pub const CHANNELS: Map<&ChannelEntry, String> = Map::new("channels");
    pub const REGISTERED_DEXES: Item<Vec<DexName>> = Item::new("registered_dexes");
    pub const ASSET_PAIRINGS: Map<&DexAssetPairing, Vec<PoolReference>> = Map::new("pool_ids");
    pub const POOL_METADATA: Map<UniquePoolId, PoolMetadata> = Map::new("pools");
    }
#[cosmwasm_schema::cw_serde]
pub struct InstantiateMsg {
    pub admin: String,
}
#[cw_ownable::cw_ownable_execute]
#[cosmwasm_schema::cw_serde]
#[derive(cw_orch::ExecuteFns)]
pub enum ExecuteMsg {
    UpdateContractAddresses {
        to_add: Vec<(UncheckedContractEntry, String)>,
        to_remove: Vec<UncheckedContractEntry>,
    },
    UpdateAssetAddresses {
        to_add: Vec<(String, AssetInfoUnchecked)>,
        to_remove: Vec<String>,
    },
    UpdateChannels {
        to_add: Vec<(UncheckedChannelEntry, String)>,
        to_remove: Vec<UncheckedChannelEntry>,
    },
    UpdateDexes {
        to_add: Vec<String>,
        to_remove: Vec<String>,
    },
    UpdatePools {
        to_add: Vec<(UncheckedPoolAddress, PoolMetadata)>,
        to_remove: Vec<UniquePoolId>,
    },
}
#[cosmwasm_schema::cw_serde]
pub struct AssetPairingFilter {
    pub asset_pair: Option<AssetPair>,
    pub dex: Option<String>,
}
#[cosmwasm_schema::cw_serde]
pub struct ContractFilter {}
#[cosmwasm_schema::cw_serde]
pub struct ChannelFilter {}
#[cosmwasm_schema::cw_serde]
pub struct AssetFilter {}
#[cosmwasm_schema::cw_serde]
pub struct AssetInfoFilter {}
#[cosmwasm_schema::cw_serde]
#[derive(Default)]
pub struct PoolMetadataFilter {
    pub pool_type: Option<PoolType>,
    }
#[cw_ownable::cw_ownable_query]
#[cosmwasm_schema::cw_serde]
#[derive(QueryResponses, cw_orch::QueryFns)]
pub enum QueryMsg {
    #[returns(ConfigResponse)]
    Config {},
    #[returns(AssetsResponse)]
    Assets {
        names: Vec<String>,
    },
    #[returns(AssetListResponse)]
    AssetList {
        filter: Option<AssetFilter>,
        start_after: Option<String>,
        limit: Option<u8>,
    },
    #[returns(AssetInfosResponse)]
    AssetInfos {
        infos: Vec<AssetInfoUnchecked>,
    },
    #[returns(AssetInfoListResponse)]
    AssetInfoList {
        filter: Option<AssetInfoFilter>,
        start_after: Option<AssetInfoUnchecked>,
        limit: Option<u8>,
    },
    #[returns(ContractsResponse)]
    Contracts {
        entries: Vec<ContractEntry>,
    },
    #[returns(ContractListResponse)]
    ContractList {
        filter: Option<ContractFilter>,
        start_after: Option<ContractEntry>,
        limit: Option<u8>,
    },
    #[returns(ChannelsResponse)]
    Channels {
        entries: Vec<ChannelEntry>,
    },
    #[returns(ChannelListResponse)]
    ChannelList {
        filter: Option<ChannelFilter>,
        start_after: Option<ChannelEntry>,
        limit: Option<u8>,
    },
    #[returns(RegisteredDexesResponse)]
    RegisteredDexes {},
    #[returns(PoolsResponse)]
    Pools { pairings: Vec<DexAssetPairing> },
    #[returns(PoolAddressListResponse)]
    PoolList {
        filter: Option<AssetPairingFilter>,
        start_after: Option<DexAssetPairing>,
        limit: Option<u8>,
    },
    #[returns(PoolMetadatasResponse)]
    PoolMetadatas { ids: Vec<UniquePoolId> },
    #[returns(PoolMetadataListResponse)]
    PoolMetadataList {
        filter: Option<PoolMetadataFilter>,
        start_after: Option<UniquePoolId>,
        limit: Option<u8>,
    },
}
#[cosmwasm_schema::cw_serde]
pub struct MigrateMsg {}
#[cosmwasm_schema::cw_serde]
pub struct ConfigResponse {
    pub next_unique_pool_id: UniquePoolId,
}
#[cosmwasm_schema::cw_serde]
pub struct AssetsResponse {
    pub assets: Vec<AssetMapEntry>,
}
#[cosmwasm_schema::cw_serde]
pub struct AssetListResponse {
    pub assets: Vec<AssetMapEntry>,
}
#[cosmwasm_schema::cw_serde]
pub struct AssetInfosResponse {
    pub infos: Vec<AssetInfoMapEntry>,
}
#[cosmwasm_schema::cw_serde]
pub struct AssetInfoListResponse {
    pub infos: Vec<AssetInfoMapEntry>,
}
#[cosmwasm_schema::cw_serde]
pub struct ContractsResponse {
    pub contracts: Vec<ContractMapEntry>,
}
#[cosmwasm_schema::cw_serde]
pub struct ContractListResponse {
    pub contracts: Vec<ContractMapEntry>,
}
#[cosmwasm_schema::cw_serde]
pub struct ChannelsResponse {
    pub channels: Vec<ChannelMapEntry>,
}
#[cosmwasm_schema::cw_serde]
pub struct ChannelListResponse {
    pub channels: Vec<ChannelMapEntry>,
}
#[cosmwasm_schema::cw_serde]
pub struct RegisteredDexesResponse {
    pub dexes: Vec<String>,
}
#[cosmwasm_schema::cw_serde]
pub struct PoolAddressListResponse {
    pub pools: Vec<AssetPairingMapEntry>,
}
#[cosmwasm_schema::cw_serde]
pub struct PoolsResponse {
    pub pools: Vec<AssetPairingMapEntry>,
}
#[cosmwasm_schema::cw_serde]
pub struct PoolMetadatasResponse {
    pub metadatas: Vec<PoolMetadataMapEntry>,
}
#[cosmwasm_schema::cw_serde]
pub struct PoolMetadataListResponse {
    pub metadatas: Vec<PoolMetadataMapEntry>,
}