%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     本服BOSS协议入口/次元幻魔
%%% @end
%%%-------------------------------------------------------------------
-module(pp_local_boss).
-author("liushl").

-include("server.hrl").
-include("local_boss.hrl").
-include("def_module.hrl").
-include("figure.hrl").
-include("errcode.hrl").
-include("scene.hrl").
-include("common.hrl").
-include("def_goods.hrl").
%% API
-export([handle/3]).

%% 世界BOSS-活动状态
handle(46001, Player, []) ->
    world_boss_mgr:get_world_boss_act_state(Player#player_status.sid),
    ok;

%% 世界BOSS-列表信息
handle(46002, Player, []) ->
    world_boss_mgr:get_world_boss_info(Player#player_status.sid),
    ok;

%% 世界BOSS-血量
handle(46003, Player, [BossId]) ->
    world_boss_mgr:get_world_boss_hp(Player#player_status.sid, BossId),
    ok;

%% 世界BOSS-周榜
handle(46004, Player, [BossId]) ->
    MyScore = lib_week:get_count(Player#player_status.id, ?MOD_LOCAL_BOSS, ?WORLD_BOSS_WEEK_SCORE, BossId),
    world_boss_mgr:get_world_boss_week_rank(Player#player_status.sid, BossId, MyScore),
    ok;

%% 世界BOSS-开启护盾礼包
handle(46006, Player, [BossId, No]) ->
    #player_status{scene = SceneId, scene_pool_id = PoolId} = Player,
    case data_local_boss:get_world_boss_info(BossId) of
        #base_world_boss_info{boss_scene = SceneId} when BossId =:= PoolId ->
            world_boss_mgr:get_shield_award(Player#player_status.id, BossId, No);
        _ ->
            ok
    end,
    ok;

%% 退出BOSS场景
handle(46010, Player, []) ->
    case local_boss_api:is_local_boss_scene(Player#player_status.scene) of
        true  ->
            NewPlayer = lib_scene:change_scene(Player, 0, 0, 0, 0, 0, []),
            {ok, NewPlayer};
        false ->
            ok
    end;

%% 赏金BOSS-次数
handle(46011, Player, []) ->
    {Count, TotalTimes} = local_boss_api:get_daily_used(Player#player_status.id),
    DailyBuy = lib_daily:get_count(Player#player_status.id, ?MOD_LOCAL_BOSS, ?COUNT_REWARD_BOSS_BUY),
    {ok, Bin} = pt_460:write(46011, [Count, TotalTimes, DailyBuy]),
    lib_server_send:send_to_sid(Player#player_status.sid, Bin),
    ok;

%% 赏金BOSS-列表信息
handle(46012, Player, []) ->
    #player_status{
        sid = Sid,
        id = RoleId,
        local_boss = #status_local_boss{boss_focus = FocusList}
    } = Player,
    BossType = ?MON_REWARD_BOSS,
    FocusList1 =
    case lists:keyfind(BossType, 1, FocusList) of
        {_, TypeFocusL} -> TypeFocusL;
        _  -> []
    end,
    AskList = [{?MOD_LOCAL_BOSS, ?COUNT_REWARD_BOSS_COUNTER_KILL, BossId}|| BossId <- data_local_boss:get_all_reward_boss()],
    CounterInfo = lib_counter:get_count(RoleId, AskList),
    Info = [{BossId, Count} || {{_, _, BossId}, Count} <- CounterInfo],
    reward_boss_mgr:get_reward_boss_info(Sid, FocusList1, Info),
    ok;

%% 赏金BOSS-击杀日志
handle(46013, Player, []) ->
    reward_boss_mgr:get_reward_boss_drop_log(Player#player_status.sid),
    ok;

%% 赏金BOSS-鼓舞
handle(46014, Player, [Type]) when Type =:= 1 orelse Type =:= 2 ->
    #player_status{id = RoleId, pid = Pid, scene = SceneId, scene_pool_id = BossId, copy_id = CopyId} = Player,
    IsUnite = custom_unite_buff:check_buff(Player,encourage_free),
    IsRewardBossScene = local_boss_api:is_reward_boss_scene(SceneId),
    IsRewardDunScene  = lib_dungeon_guide_boss:is_in_reward_boss_dun(Player),
    if 
        IsRewardBossScene ->
            is_integer(BossId) andalso reward_boss_mgr:encourage_attr(RoleId, Pid, BossId, Type, IsUnite);
        IsRewardDunScene ->
            {Mod, Fun, Args} = {lib_dungeon_guide_boss, encourage_attr, [RoleId, Pid, BossId, Type, IsUnite]},
            mod_dungeon:apply(CopyId, Mod, Fun, Args);
        true ->
            skip
    end,
    ok;

%% BOSS-进入
handle(46016, Player, [BossId]) ->
    #player_status{sid = Sid} = Player,
    case local_boss_api:ask_enter_boss_scene(Player, BossId, false) of
        {false, Err} ->
            {ok, Bin} = pt_460:write(46016, [Err, BossId]),
            lib_server_send:send_to_sid(Sid, Bin);
        {true, NewPlayer} ->
            {ok, NewPlayer};
        _ ->
            ok
    end;

%% 赏金BOSS-鼓舞次数查询
handle(46019, Player, [BossId]) when BossId == ?REWARD_BOSS_DUN_MON ->
    #player_status{id = RoleId, sid = Sid, copy_id = CopyId} = Player,
    case lib_dungeon_guide_boss:is_in_reward_boss_dun(Player) of
        true ->
            {Mod, Fun, Args} = {lib_dungeon_guide_boss, get_encourage_info, [BossId, RoleId, Sid]},
            mod_dungeon:apply(CopyId, Mod, Fun, Args);
        _ ->
            lib_server_send:send_to_sid(Sid, pt_460, 46019, [BossId, 0, 0])
    end;

handle(46019, Player, [BossId]) ->
    reward_boss_mgr:get_encourage_info(Player#player_status.id, BossId),
    ok;

%% BOSS 关注操作
handle(46024, Player, [BossType, BossId, 1])
 when BossType == ?MON_REWARD_BOSS orelse BossType == ?MON_DESERTED_BOSS ->
    #player_status{
        sid = Sid,
        id = RoleId,
        figure = #figure{lv = Lv},
        local_boss = #status_local_boss{boss_focus = FocusList} = LocalBoss
    } = Player,
    TypeFocusL1 =
    case lists:keyfind(BossType, 1, FocusList) of
        {_, TypeFocusL} -> TypeFocusL;
        _  -> []
    end,
    MonCfg =
    if
        BossType == ?MON_REWARD_BOSS ->
            data_local_boss:get_reward_boss_info(BossId);
        true ->
            data_deserted_boss:get_boss_cfg(BossId)
    end,
    case local_boss_api:focus_check(MonCfg, Lv) of
        true ->
            case lists:member(BossId, TypeFocusL1) of
                false ->
                    NewTypeFocusL1 = [BossId|TypeFocusL1],
                    NewFocus = lists:keystore(BossType, 1, FocusList, {BossType, NewTypeFocusL1}),
                    NewLocalBoss = LocalBoss#status_local_boss{boss_focus = NewFocus},
                    db:execute(?SQL_SAVE_BOSS_FOCUS, [RoleId, BossId, BossType]),
                    {ok, Bin} = pt_460:write(46024, [1, BossType, BossId, 1]),
                    lib_server_send:send_to_sid(Sid, Bin),
                    Player1 = Player#player_status{local_boss = NewLocalBoss},
                    {ok, Player1};
                true ->
                    ok
            end;
        false ->
            {ok, Bin} = pt_460:write(46024, [?ERRCODE(err460_no_lv), BossType, BossId, 1]),
            lib_server_send:send_to_sid(Sid, Bin),
            ok
    end;
handle(46024, Player, [BossType, BossId, 0])
 when BossType == ?MON_REWARD_BOSS orelse BossType == ?MON_DESERTED_BOSS ->
    #player_status{
        sid = Sid, id = RoleId,
        local_boss = #status_local_boss{boss_focus = FocusList} = LocalBoss
    } = Player,
    TypeFocusL1 = case lists:keyfind(BossType, 1, FocusList) of
        {_, TypeFocusL} -> TypeFocusL;
        _  -> []
    end,
    case lists:member(BossId, TypeFocusL1) of
        true  ->
            NewTypeFocusL1 = lists:delete(BossId, TypeFocusL1),
            NewFocus = lists:keystore(BossType, 1, FocusList, {BossType, NewTypeFocusL1}),
            NewLocalBoss = LocalBoss#status_local_boss{boss_focus = NewFocus},
            db:execute(?SQL_DEL_BOSS_FOCUS, [RoleId, BossId]),
            {ok, Bin} = pt_460:write(46024, [1, BossType, BossId, 0]),
            lib_server_send:send_to_sid(Sid, Bin),
            Player1 = Player#player_status{local_boss = NewLocalBoss},
            {ok, Player1};
        false ->
            ok
    end;

%% 活动BOSS-信息
handle(46026, Player, []) ->
    act_boss_mgr:ask_boss_info(Player#player_status.sid),
    ok;

%% 活动BOSS-场景的BOSS信息
handle(46027, Player, []) ->
    act_boss_mgr:ask_my_scene_boss(Player#player_status.sid),
    ok;

%% 活动BOSS-点击立即前往某个活动场景
handle(46028, Player, [SceneId]) ->
    case lib_scene:check_enter(Player, 0, SceneId, ?TRANS_TYPE_WORLD) of
        {true, _, _}  ->
            act_boss_mgr:ask_enter_scene(Player#player_status.pid, SceneId);
        {false, Error} ->
            {ok, Bin} = pt_460:write(46028, [Error]),
            lib_server_send:send_to_sid(Player#player_status.sid, Bin)
    end,
    ok;

%% 活动BOSS-伤害排名信息-进入BOSS区域请求
handle(46029, Player, [MonId]) ->
    act_boss_mgr:ask_mon_info(Player#player_status.scene, Player#player_status.scene_pool_id, MonId, Player#player_status.sid),
    ok;

%% 活动BOSS-分享
handle(46031, Player, [MonId]) ->
    act_boss_mgr:share_position(Player#player_status.id, MonId, Player#player_status.scene,
        Player#player_status.scene_pool_id, Player#player_status.x, Player#player_status.y),
    ok;

%% 召唤独享BOSS
handle(46032, Player, [BossId]) ->
    #player_status{sid = Sid} = Player,
    case unshared_boss:use_refresh_card(Player, BossId) of
        {false, Err} ->
            {ok, Bin} = pt_460:write(46032, [Err]),
            lib_server_send:send_to_sid(Sid, Bin);
        {true, NewPlayer} ->
            {ok, Bin} = pt_460:write(46032, [1]),
            lib_server_send:send_to_sid(Sid, Bin),
            {ok, NewPlayer}
    end;

handle(46101, Player, [Level]) ->
    #player_status{sid = Sid, id = RoleId, local_boss = #status_local_boss{boss_focus = FocusList}} = Player,
    case lists:keyfind(?MON_DESERTED_BOSS, 1, FocusList) of
        {_, TypeFocusL} -> TypeFocusL;
        _  -> TypeFocusL = []
    end,
    deserted_boss_mgr:get_deserted_boss_info(RoleId, Sid, node(), Level, TypeFocusL);

handle(46102, Player, []) ->
    #player_status{sid = Sid, local_boss = #status_local_boss{
        deserted_boss_tired = BossTired,
        deserted_elite_tired = EliteTired
    }} = Player,
    {ok, Bin} = pt_461:write(46102, [BossTired, EliteTired]),
    lib_server_send:send_to_sid(Sid, Bin),
    ok;

handle(46103, Player, [BossId]) ->
    #player_status{sid = Sid} = Player,
    deserted_boss_mgr:get_boss_hurt_info(Sid, node(), BossId),
    ok;

%% BOSS-进入
handle(46106, Player, [BossId]) ->
    #player_status{sid = Sid} = Player,
    case local_boss_api:deserted_boss_enter(Player, BossId, [normal_enter]) of
        {false, Err} ->
            {ok, Bin} = pt_461:write(46106, [Err, BossId]),
            lib_server_send:send_to_sid(Sid, Bin);
        {true, NewPlayer} ->
            {ok, NewPlayer};
        _ ->
            {ok, BinData} = pt_461:write(46106, [?SUCCESS, BossId]),
            lib_server_send:send_to_sid(Sid, BinData),
            ok
    end;

%% boss刷新卡刷新boss
handle(46107, Player, [Type, BossId]) when Type == 1 ->
    #player_status{sid = Sid, scene = SceneId} = Player,
    {Res, NPlayer} =
    case data_scene:get(SceneId) of
        #ets_scene{type = ?SCENE_TYPE_OUTSIDE} ->
            local_boss_api:use_goods_refresh_boss(Player, Type, BossId);
        _ ->
            {?ERRCODE(err461_not_in_normal_scene), Player}
    end,
    {ok, BinData} = pt_461:write(46107, [Res, Type, BossId]),
    lib_server_send:send_to_sid(Sid, BinData),
    {ok, NPlayer};

handle(46107, Player, [Type, BossId]) when Type == 2 ->
    #player_status{sid = Sid, scene = SceneId} = Player,
    BossCfgRet = data_deserted_boss:get_boss_cfg(BossId),
    {Res, NPlayer} =
    if
        not is_record(BossCfgRet, base_deserted_boss_info) ->
            {?MISSING_CONFIG, Player};
        true ->
            #base_deserted_boss_info{level = Level} = BossCfgRet,
            #base_deserted_level{scene = Scene, cls_scene = ClsScene} = data_deserted_boss:get_level(Level),
            if
                SceneId == Scene orelse SceneId == ClsScene ->
                    local_boss_api:use_goods_refresh_boss(Player, Type, BossId);
                true ->
                    {?ERRCODE(err461_not_in_scene), Player}
            end
    end,
    {ok, BinData} = pt_461:write(46107, [Res, Type, BossId]),
    lib_server_send:send_to_sid(Sid, BinData),
    {ok, NPlayer};

%% 星域幻魔玩家免费复活次数
handle(46108, Player, []) ->
    HasFreeTimes = lib_pet_api:pet_life_skill_about_deserted_revive_free(Player),
    UseTimes = lib_daily:get_count(Player#player_status.id, ?MOD_DESERTED_BOSS, 3),
    {ok, BinData} = pt_461:write(46108, [max(0, HasFreeTimes - UseTimes)]),
    lib_server_send:send_to_sid(Player#player_status.sid, BinData),
    {ok, Player};

%% 获得精英怪物存活状况
handle(46109, Player, [Level]) ->
    #player_status{sid = Sid} = Player,
    deserted_boss_mgr:get_elite_mon_info(Sid, node(), Level);

%% 赏金boss/星域幻魔无敌时间查询
handle(Cmd, Player, []) when Cmd == 46033 orelse Cmd == 46111 ->
    #player_status{id = RoleId, sid = Sid,
        reb_protect_time  = RebProtectTime
        ,deb_protect_time = DebProtectTime
    } = Player,
    case Cmd of
        46033 ->
            UseTimes = lib_daily:get_count(RoleId, ?MOD_LOCAL_BOSS, ?REWARD_BOSS_PROTECT_USE_TIMES),
            lib_server_send:send_to_sid(Sid, pt_460, 46033, [UseTimes, RebProtectTime]);
        46111 ->
            UseTimes = lib_daily:get_count(RoleId, ?MOD_DESERTED_BOSS, ?DESERTED_BOSS_PROTECT_USE_TIMES),
            lib_server_send:send_to_sid(Sid, pt_461, 46111, [UseTimes, DebProtectTime])
    end,
    ok;

%% 赏金免战时间使用
handle(46034, Player, []) ->
    #player_status{id = RoleId, sid = Sid, scene = SceneId,
        reb_protect_time = ProtectTime, reb_protect_ref = OldRef
    } = Player,
    CfgProtectTime = data_local_boss:get_local_boss_kv(role_protect_time),
    UseTimes = lib_daily:get_count(RoleId, ?MOD_LOCAL_BOSS, ?REWARD_BOSS_PROTECT_USE_TIMES),
    NowTime  = utime:unixtime(),
    CheckCanUse = local_boss_api:check_can_use_protect_time(Player),
    case data_scene:get(SceneId) of
        #ets_scene{type = SceneType} -> ok;
        _ -> SceneType = 0
    end,
    CheckScene = SceneType == ?SCENE_TYPE_REWARD_BOSS,
    if
        not CheckCanUse ->
            lib_server_send:send_to_sid(Sid, pt_460, 46034,
                [?ERRCODE(err460_cannot_use_protect_time), UseTimes, ProtectTime]
            ),
            ok;
        not CheckScene ->
            lib_server_send:send_to_sid(Sid, pt_460, 46034,
                [?FAIL, UseTimes, ProtectTime]
            ),
            ok;
        true ->
            case UseTimes >= 1 of
                true ->
                    lib_server_send:send_to_sid(Sid, pt_460, 46034,
                        [?ERRCODE(err460_protect_time_not_enough), UseTimes, ProtectTime]
                    ),
                    ok;
                false when ProtectTime > NowTime ->
                    lib_server_send:send_to_sid(Sid, pt_460, 46034,
                        [?ERRCODE(err460_not_need_use), UseTimes, ProtectTime]
                    ),
                    ok;
                false ->
                    lib_daily:increment(RoleId, ?MOD_LOCAL_BOSS, ?REWARD_BOSS_PROTECT_USE_TIMES),
                    Now = utime:unixtime(),
                    NewTime = case ProtectTime > Now of
                                  true  -> ProtectTime + CfgProtectTime;
                                  false -> Now + CfgProtectTime
                              end,
                    local_boss_api:save_db_protect_time(RoleId, 1, NewTime),
                    lib_server_send:send_to_sid(Sid, pt_460, 46034, [?SUCCESS, UseTimes + 1, NewTime]),
                    Ref = local_boss_api:waiting_for_protect_time_over(OldRef, NewTime, Now, ?REWARD_BOSS_PROTECT_TIME),
                    %% 更新玩家进程记录的数据
                    Player2 = local_boss_api:update_protect_time(Player, NewTime, ?REWARD_BOSS_PROTECT_TIME),
                    {ok, Player2#player_status{reb_protect_ref = Ref}}
            end
    end;

%% 星域幻魔免战时间使用
handle(46112, Player, []) ->
    #player_status{id = RoleId, sid = Sid, scene = SceneId,
        deb_protect_time = ProtectTime, deb_protect_ref = OldRef
    } = Player,
    CfgProtectTime = data_deserted_boss:get_kv(role_protect_time),
    UseTimes = lib_daily:get_count(RoleId, ?MOD_DESERTED_BOSS, ?DESERTED_BOSS_PROTECT_USE_TIMES),
    NowTime  = utime:unixtime(),
    CheckCanUse = local_boss_api:check_can_use_protect_time(Player),
    case data_scene:get(SceneId) of
        #ets_scene{type = SceneType} -> ok;
        _ -> SceneType = 0
    end,
    CheckScene = SceneType == ?SCENE_TYPE_DESERTED_BOSS,
    if
        not CheckCanUse ->
            lib_server_send:send_to_sid(Sid, pt_460, 46034,
            [?ERRCODE(err461_cannot_use_protect_time), UseTimes, ProtectTime]
            ),
            ok;
        not CheckScene ->
            lib_server_send:send_to_sid(Sid, pt_460, 46034,
                [?FAIL, UseTimes, ProtectTime]
            ),
            ok;
        true ->
            case UseTimes >= 1 of
                true ->
                    lib_server_send:send_to_sid(Sid, pt_461, 46112,
                        [?ERRCODE(err461_protect_time_not_enough), UseTimes, ProtectTime]
                    ),
                    ok;
                false when ProtectTime > NowTime ->
                    lib_server_send:send_to_sid(Sid, pt_461, 46112,
                        [?ERRCODE(err461_not_need_use), UseTimes, ProtectTime]
                    ),
                    ok;
                false ->
                    lib_daily:increment(RoleId, ?MOD_DESERTED_BOSS, ?DESERTED_BOSS_PROTECT_USE_TIMES),
                    Now = utime:unixtime(),
                    NewTime = case ProtectTime > Now of
                                  true  -> ProtectTime + CfgProtectTime;
                                  false -> Now + CfgProtectTime
                              end,
                    local_boss_api:save_db_protect_time(RoleId, 2, NewTime),
                    lib_server_send:send_to_sid(Sid, pt_461, 46112, [?SUCCESS, UseTimes + 1, NewTime]),
                    Ref = local_boss_api:waiting_for_protect_time_over(OldRef, NewTime, Now, ?DESERTED_BOSS_PROTECT_TIME),
                    %% 更新玩家进程记录的数据
                    Player2 = local_boss_api:update_protect_time(Player, NewTime, ?DESERTED_BOSS_PROTECT_TIME),
                    {ok, Player2#player_status{deb_protect_ref = Ref}}
            end
    end;

%% 获取幻魔之家怪物信息
handle(46201, Player, [SubModule, Level, GuildId]) ->
    #player_status{id = RoleId, sid = Sid} = Player,
    home_boss_mgr:get_deserted_boss_info(SubModule, [RoleId, GuildId, Sid, Level]),
    ok;

handle(46202, Player, [SubModule, BossId]) ->
    #player_status{sid = Sid, figure = #figure{guild_id = GuildId}} = Player,
    home_boss_mgr:get_boss_hurt_info(SubModule, GuildId, Sid, BossId),
    ok;

handle(46204, Player, [SubModule, BossId]) ->
    local_boss_api:enter_home_boss(Player, SubModule, BossId);

%% 社团之家归属社团信息
handle(46205, Player, []) ->
    #player_status{sid = Sid, id = RoleId, figure = #figure{guild_id = GuildId}} = Player,
    home_boss_mgr:get_top_guild_info(Sid, RoleId, GuildId);

handle(_Cmd, _Player, _Arg) ->
    erlang:display({?MODULE, ?LINE, _Cmd, _Arg}),
    ok.