use bd2::prost::Message;
use bd2::proto::proto_net::{
    MonsterHuntScheduleHistory, MonsterHuntScheduleInfo, MonsterHuntScheduleInfoRequest,
    MonsterHuntScheduleInfoResponse, Notify, SeasonInfo,
};
use common::packet_code::PacketCodeType;
use crypto::network::GameResponse;
use serde_json::Value;
use sqlx::SqlitePool;
use tracing::info;

pub async fn handle(
    _pool: &SqlitePool,
    _uid: i64,
    req: MonsterHuntScheduleInfoRequest,
) -> GameResponse {
    info!("Handling MonsterHuntScheduleInfoRequest: {:?}", req);

    let data: Value = serde_json::from_str(include_str!(
        "../../../../data/starter/monster_hunt_schedule_info.json"
    ))
    .unwrap();

    let monster_hunt_schedule_info = data
        .get("monsterHuntScheduleInfo")
        .and_then(|v| v.as_array())
        .map(|arr| {
            arr.iter()
                .map(|entry| {
                    // Extract SeasonInfo if present
                    let season_info = entry.get("seasonInfo").map(|season| SeasonInfo {
                        season: season
                            .get("season")
                            .and_then(|v| v.as_i64())
                            .map(|v| v as i32),
                        start_time: season.get("startTime").and_then(|v| v.as_i64()),
                        end_time: season.get("endTime").and_then(|v| v.as_i64()),
                        error_flag: season.get("errorFlag").and_then(|v| v.as_bool()),
                        return_flag: season.get("returnFlag").and_then(|v| v.as_bool()),
                        rank_reward_group_id: season
                            .get("rankRewardGroupId")
                            .and_then(|v| v.as_i64())
                            .map(|v| v as i32),
                    });

                    MonsterHuntScheduleInfo {
                        season_info,
                        monster_hunt_id: entry
                            .get("monsterHuntId")
                            .and_then(|v| v.as_i64())
                            .map(|v| v as i32),
                        info_open_day: entry
                            .get("infoOpenDay")
                            .and_then(|v| v.as_i64())
                            .map(|v| v as i32),
                        calculate_end_date: entry.get("calculateEndDate").and_then(|v| v.as_i64()),
                        error_flag: entry.get("errorFlag").and_then(|v| v.as_bool()),
                        independent_flag: entry.get("independentFlag").and_then(|v| v.as_bool()),
                        rank_reward_group_id: entry
                            .get("rankRewardGroupId")
                            .and_then(|v| v.as_i64())
                            .map(|v| v as i32),
                    }
                })
                .collect::<Vec<_>>()
        })
        .unwrap_or_default();

    let season_history = data
        .get("seasonHistory")
        .and_then(|v| v.as_array())
        .map(|arr| {
            arr.iter()
                .map(|entry| MonsterHuntScheduleHistory {
                    season: entry
                        .get("season")
                        .and_then(|v| v.as_i64())
                        .map(|v| v as i32),
                    monster_hunt_id: entry
                        .get("monsterHuntId")
                        .and_then(|v| v.as_i64())
                        .map(|v| v as i32),
                    error_flag: entry.get("errorFlag").and_then(|v| v.as_bool()),
                    hidden: entry.get("hidden").and_then(|v| v.as_bool()),
                })
                .collect::<Vec<_>>()
        })
        .unwrap_or_default();

    let start_regular_season = data
        .get("startRegularSeason")
        .and_then(|v| v.as_i64())
        .map(|v| v as i32);

    let response = MonsterHuntScheduleInfoResponse {
        monster_hunt_schedule_info,
        start_regular_season,
        season_history,
    };

    let resp_bytes = response.encode_to_vec();

    let notify = Notify {
        achievement_update_info: vec![],
        mission_update_info: vec![],
        event_mission_update_info: vec![],
        active_login_event: vec![1, 2, 628, 629],
        active_contents_info: vec![],
        ll_type: Some("".to_string()),
        is_purchasing_disabled: Some(false),
        maintenance_start_date: Some(1688646600000),
        notice_last_seq: Some(8909),
        ..Default::default()
    };

    let (route, code) = PacketCodeType::Common.info();
    GameResponse::success(route, &resp_bytes, code).with_notify(&notify)
}
