%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     护送协议入口
%%% @end
%%%-------------------------------------------------------------------
-module(pp_convoy).
-author("liushl").

-include("server.hrl").
-include("convoy.hrl").
-include("def_module.hrl").
-include("errcode.hrl").
-include ("def_act_label.hrl").
-include ("figure.hrl").
-include ("common.hrl").

%% API
-export([handle/3]).

%% 获取信息
handle(50000, Player, _) ->
    #player_status{
        id = RoleId, sid = Sid, action_lock = ActionLock, role_convoy = RoleConvoy
    } = Player,
    #role_convoy{convoy_id = ConvoyId, start_time = StartTime, pray_val = PrayVal, is_double = IsChooseDouble} = RoleConvoy,
    NewConvoyId =
    if ConvoyId == 0 ->
            NewConvoyId0 = convoy_api:rand_convoy_id(),
            lib_counter:set_count(RoleId, ?MOD_CONVOY, 6, NewConvoyId0),
            NewConvoyId0;
        true ->
            ConvoyId
    end,
    DailyConvoy = lib_daily:get_count(RoleId, ?MOD_CONVOY, ?CONVOY_COUNTER_DAILY_CONVOY),
    IsConvoy = 
    case convoy_api:is_convoy_action(ActionLock) of
        true  -> 1;
        false -> 0
    end,
    EndTime = 
    if StartTime =/= 0 ->
            OverTime = data_convoy:get_convoy_kv(convoy_overtime),
            StartTime + OverTime;
        true -> 0
    end,
    ActDouble = convoy_api:act_is_double(),
    IsDouble =
     if IsChooseDouble =/= 0 orelse ActDouble == 2 -> %% 双倍进行中
            1;
        true -> 0 %% 非双倍
    end,
    lib_server_send:send_to_sid(Sid, pt_500, 50000, [NewConvoyId, DailyConvoy, IsConvoy, EndTime, PrayVal, IsDouble]),
    NewRoleConvoy = RoleConvoy#role_convoy{convoy_id = NewConvoyId},
    NewPlayer = Player#player_status{role_convoy = NewRoleConvoy},
    if NewConvoyId =/= ConvoyId ->
            convoy_api:db_update_role_convoy(RoleId, RoleConvoy);
        true ->
            skip
    end,
    {ok, NewPlayer};

%% 提升品质
handle(50001, Player, [_AutoBuy]) ->
    #player_status{
        id = RoleId, sid = Sid, figure = #figure{name = Name, vip = Vip}, 
        role_convoy = RoleConvoy, action_lock = ActionLock
    } = Player,
    #role_convoy{convoy_id = ConvoyId, pray_val = PrayVal} = RoleConvoy,
    ConvoyOpen = lib_module:is_open(Player, ?MOD_CONVOY),
    IsConvoyAction = convoy_api:is_convoy_action(ActionLock),
    DailyConvoy = lib_daily:get_count(Player#player_status.id, ?MOD_CONVOY, ?CONVOY_COUNTER_DAILY_CONVOY),
    CountLimit  = DailyConvoy >= ?CONVOY_MAX_COUNT,
    ConvoyCfg = data_convoy:get_convoy_object(ConvoyId),
    if
        not ConvoyOpen ->
            lib_server_send:send_to_sid(Sid, pt_500, 50001, [?ERRCODE(lv_limit), 0, 0, []]);
        IsConvoyAction ->
            lib_server_send:send_to_sid(Sid, pt_500, 50001, [ActionLock, 0, 0, []]);
        CountLimit ->
            lib_server_send:send_to_sid(Sid, pt_500, 50001, [?ERRCODE(err500_husong_end), 0, 0, []]);
        not is_record(ConvoyCfg, base_convoy_object) ->
            lib_server_send:send_to_sid(Sid, pt_500, 50001, [?MISSING_CONFIG, 0, 0, []]);
        ConvoyCfg#base_convoy_object.next_id == 0 ->
            lib_server_send:send_to_sid(Sid, pt_500, 50001, [?ERRCODE(err500_husong_quality_max), 0, 0, []]);
        true ->
            #base_convoy_object{upgrade_cost = Cost, next_id = NextId, up_next_val = NextVal, up_next_weight = Weight} = ConvoyCfg,
            Result = convoy_api:refresh_convoy_calc(PrayVal >= NextVal, Weight),
            Res =
                % case AutoBuy of
                %     1 ->
                        lib_goods_api:cost_objects_with_auto_buy(Player, Cost, convoy_refresh, ""),
                %     _ ->
                %         lib_goods_api:cost_object_list_with_check(Player, Cost, convoy_refresh, "")
                % end,
            case Res of
                {false, Error, _}  -> 
                    lib_server_send:send_to_sid(Sid, pt_500, 50001, [Error, 0, 0, []]);
                {true, Player1, CostList} ->
                    if Result == true ->
                            NewRoleConvoy = RoleConvoy#role_convoy{convoy_id = NextId, pray_val = 0};
                        true ->
                            [MinVal, MaxVal|_] = data_convoy:get_convoy_kv(convoy_up_num),
                            Val = urand:rand(MinVal, MaxVal),
                            NewPrayVal = PrayVal + Val,
                            if NewPrayVal >= NextVal ->
                                    NewRoleConvoy = RoleConvoy#role_convoy{convoy_id = NextId, pray_val = 0};
                                true ->
                                    NewRoleConvoy = RoleConvoy#role_convoy{pray_val = PrayVal + Val}
                            end
                    end,
                    Player2 = Player1#player_status{role_convoy = NewRoleConvoy},
                    %% 保存状态
                    convoy_api:db_update_role_convoy(RoleId, NewRoleConvoy),
                    lib_log_api:log_convoy_refresh(
                        [RoleId, Name, ConvoyId, NewRoleConvoy#role_convoy.convoy_id, util:term_to_bitstring(CostList), Vip, utime:unixtime()]
                    ),
                    lib_server_send:send_to_sid(Sid, pt_500, 50001, [?SUCCESS, NewRoleConvoy#role_convoy.convoy_id, NewRoleConvoy#role_convoy.pray_val, CostList]),
                    convoy_api:refresh_convoy_cost(Player2, Cost, CostList, NextId, ConvoyId),
                    {ok, Player2}
            end
    end;

%% 开始护送
handle(50002, Player, [IsDouble]) ->
    #player_status{
        id = RoleId, sid = Sid, role_convoy = RoleConvoy, figure = Figure, action_lock = ActionLock,
        scene = SceneId, scene_pool_id = PoolId, copy_id = CopyId, x = X, y = Y} = Player,
    #role_convoy{convoy_id = ConvoyId} = RoleConvoy,
    ConvoyOpen = lib_module:is_open(Player, ?MOD_CONVOY),
    IsConvoyAction = convoy_api:is_convoy_action(ActionLock),
    IsNearNpc = convoy_api:is_near_npc(Player),
    DailyConvoy = lib_daily:get_count(Player#player_status.id, ?MOD_CONVOY, ?CONVOY_COUNTER_DAILY_CONVOY),
    CountLimit  = DailyConvoy >= ?CONVOY_MAX_COUNT,
    IsSupporting = lib_guild_support_mod:role_is_supporting(Player),
    ConvoyCfg = data_convoy:get_convoy_object(ConvoyId),
    ActDouble = convoy_api:act_is_double(),
    if
        not ConvoyOpen ->
            lib_server_send:send_to_sid(Sid, pt_500, 50002, [?ERRCODE(lv_limit), 0, IsDouble]);
        IsConvoyAction ->
            lib_server_send:send_to_sid(Sid, pt_500, 50002, [ActionLock, 0, IsDouble]);
        CountLimit ->
            lib_server_send:send_to_sid(Sid, pt_500, 50002, [?ERRCODE(err500_husong_end), 0, IsDouble]);
        not is_record(ConvoyCfg, base_convoy_object) ->
            lib_server_send:send_to_sid(Sid, pt_500, 50002, [?MISSING_CONFIG, 0, IsDouble]);
        IsSupporting ->
            lib_server_send:send_to_sid(Sid, pt_500, 50002, [?ERRCODE(err500_husong_supporting), 0, IsDouble]);
        not IsNearNpc ->
            lib_server_send:send_to_sid(Sid, pt_500, 50002, [?ERRCODE(err500_not_near_npc), 0, IsDouble]);
        true ->
            Ret =
            if IsDouble =/= 0 andalso ActDouble =/= 2 ->
                    CostList = data_convoy:get_convoy_kv(convoy_double_cost),
                    lib_goods_api:cost_object_list_with_check(Player, CostList, double_convoy_cost, integer_to_list(IsDouble));
                true ->
                    {true, Player, []}
            end,
            case Ret of
                {true, Player0, _} ->
                    %% 次数+1
                    lib_daily:increment(RoleId, ?MOD_CONVOY, ?CONVOY_COUNTER_DAILY_CONVOY),
                    OverTime = data_convoy:get_convoy_kv(convoy_overtime),
                    NowTime  = utime:unixtime(),
                    EndTimer = erlang:send_after(round(OverTime*1000), self(), {mod, convoy_api, convoy_end, [?CONVOY_SETTLEMENT_OVERDUE]}),
                    %% 进入护送状态
                    NewConvoyInfo = RoleConvoy#role_convoy{convoy_status = ConvoyId, stage = ?CONVOY_STAGE_ONE, is_double = IsDouble, start_time = NowTime, ref = EndTimer},
                    convoy_api:db_update_role_convoy(RoleId, NewConvoyInfo),
                    Player1 = Player0#player_status{role_convoy = NewConvoyInfo, figure = Figure#figure{husong_angel_id = ConvoyId}},
                    mod_scene_agent:update(Player1, [{husong_angel_id, ConvoyId}]),
                    %% 添加活动标识
                    Player2 = lib_scene:change_act_label(Player1, ?ACT_LABEL_CONVOY, ConvoyId),
                    %% 加活动锁
                    Player3 = lib_player:setup_action_lock(Player2, ?ERRCODE(err500_husong_start)),
                    Player4 = lib_player:count_player_speed(Player3),
                    % {ok, Player4} = lib_player:change_pkstatus(Player3, ?PK_PEACE_ULTIMATE, true),
                    %% 触发孩子任务
                    Player6 = lib_child_task:finish_husong(Player4),
                    lib_dun_multi:change_scene_check(Player6),
                    %% 触发成就
                    lib_achievement_api:convoy_event(Player6, 1),
                    case data_convoy:get_top_convoy() =:= ConvoyId of
                        true  ->
                            lib_chat:send_TV({all}, ?MOD_CONVOY, 2, [Figure#figure.name]);
                        false ->
                            ok
                    end,
                    contract_task_api:convoy_trigger(RoleId, 1),
                    {ok, Player7} = pp_convoy:handle(50000, Player6, []),
                    %% 更新场景信息
                    {ok, Bin} = pt_500:write(50010, [RoleId, ConvoyId]),
                    lib_server_send:send_to_area_scene(SceneId, PoolId, CopyId, X, Y, Bin),
                    lib_server_send:send_to_sid(Sid, pt_500, 50002, [?SUCCESS, ConvoyId, IsDouble]),
                    {ok, Player7};
                {false, Error, _} ->
                    lib_server_send:send_to_sid(Sid, pt_500, 50002, [Error, ConvoyId, IsDouble]),
                    ok
            end
    end;

%% 完成阶段护送
handle(50003, Player, [Type]) ->
    #player_status{
        sid = Sid, role_convoy = RoleConvoy, action_lock = ActionLock} = Player,
    #role_convoy{convoy_id = ConvoyId, convoy_status = Convoying, stage = Stage} = RoleConvoy,
    ConvoyOpen      = lib_module:is_open(Player, ?MOD_CONVOY),
    IsConvoyAction  = convoy_api:is_convoy_action(ActionLock),
    IsNearTarget    = convoy_api:is_near_target(Player, Type),
    IsSupporting    = lib_guild_support_mod:role_is_supporting(Player),
    ConvoyCfg       = data_convoy:get_convoy_object(ConvoyId),
    if
        not ConvoyOpen ->
            lib_server_send:send_to_sid(Sid, pt_500, 50003, [?ERRCODE(lv_limit), Type]);
        not is_record(ConvoyCfg, base_convoy_object) ->
            lib_server_send:send_to_sid(Sid, pt_500, 50003, [?MISSING_CONFIG, Type]);
        not IsConvoyAction andalso Convoying == 0 ->
            lib_server_send:send_to_sid(Sid, pt_500, 50003, [?ERRCODE(err500_husong_not_start), Type]);
        IsSupporting ->
            lib_server_send:send_to_sid(Sid, pt_500, 50003, [?ERRCODE(err500_husong_supporting), Type]);
        not IsNearTarget ->
            lib_server_send:send_to_sid(Sid, pt_500, 50003, [?ERRCODE(err500_not_near_npc), Type]);
        Stage =/= Type orelse (Stage =/= ?CONVOY_STAGE_ONE andalso Stage =/= ?CONVOY_STAGE_TWO) ->
            lib_server_send:send_to_sid(Sid, pt_500, 50003, [?ERRCODE(err500_husong_stage_wrong), Type]);
        true ->
            {ok, NewPlayer} = convoy_api:finish_convoy(Player, Type),
            {ok, NewPlayer} 
    end;

%% 取消护送
handle(50008, Player, _) ->
    #player_status{
        sid = Sid, role_convoy = RoleConvoy, action_lock = ActionLock} = Player,
    #role_convoy{convoy_status = Convoying} = RoleConvoy,
    ConvoyOpen      = lib_module:is_open(Player, ?MOD_CONVOY),
    IsConvoyAction  = convoy_api:is_convoy_action(ActionLock),
    if
        not ConvoyOpen ->
            lib_server_send:send_to_sid(Sid, pt_500, 50008, [?ERRCODE(lv_limit)]);
        not IsConvoyAction andalso Convoying == 0 ->
            lib_server_send:send_to_sid(Sid, pt_500, 50008, [?ERRCODE(err500_husong_not_start)]);
        true ->
            {ok, NewPlayer} = convoy_api:cancel_convoy(Player),
            lib_server_send:send_to_sid(Sid, pt_500, 50008, [?SUCCESS]),
            {ok, NewPlayer}
    end;

%% 切换到npc处
handle(50009, Player, _) ->
    case convoy_api:transfer_to_npc(Player) of
        {false, Error} ->
            {ok, Bin} = pt_500:write(50009, [Error]),
            lib_server_send:send_to_sid(Player#player_status.sid, Bin),
            ok;
        {true, NewPlayer} ->
            {ok, Bin} = pt_500:write(50009, [?SUCCESS]),
            lib_server_send:send_to_sid(Player#player_status.sid, Bin),
            {ok, NewPlayer}
    end;

handle(_Cmd, _Player, _Data) ->
    % erlang:display({"[LIUSHL]", erlang:localtime(), ?MODULE, ?LINE, Cmd, Data}),
    ok.
