%%%--------------------------------------
%%% @Module  : pp_task
%%% @Author  : xyao
%%% @Created : 2010.09.24
%%% @Description:  任务模块
%%%--------------------------------------
-module(pp_task).
-export([handle/3]).
-include("common.hrl").
-include("server.hrl").
-include("task.hrl").
-include("figure.hrl").
-include("def_fun.hrl").
-include("errcode.hrl").
-include("def_module.hrl").
-include("goods.hrl").
-include("def_goods.hrl").
-include("guild.hrl").
-include("predefine.hrl").

%% 获取任务列表
handle(30000, Status, _) ->
    lib_role_task:get_my_task_list(lib_task_api:ps2task_args(Status)),
    {ok,Status};

%% 触发任务
handle(30003, Status, [TaskId]) ->
    case lib_role_task:trigger(TaskId, lib_task_api:ps2task_args(Status)) of
        true -> Code = 1;
        {false, Code} -> skip
    end,
    {ok, BinData} = pt_300:write(30003, [TaskId, Code]),
    lib_server_send:send_to_sid(Status#player_status.sid, BinData),
    {ok,Status};

%% 完成任务
handle(30004, Status, [TaskId, DoubleType, SelectItemList])->
    %% 特殊的任务类型判断
    TDCfg = data_task:get(TaskId),
    TD = #task{type = _TaskType, end_npc = NpcId} = ?IF(is_record(TDCfg, task), TDCfg, #task{}),
    case check_task_finish_state(Status, TD, SelectItemList, DoubleType) of
        {false, Code} ->
            {ok, BinData} = pt_300:write(30004, [0, Code, []]),
            lib_server_send:send_to_sid(Status#player_status.sid, BinData);
        {true, Args, NewPs} ->
            #player_status{id = _RoleId, sid = Sid} = NewPs,
            TaskArgs = lib_task_api:ps2task_args(NewPs),
            case lib_role_task:finish(TaskId, Args, TaskArgs) of
                true ->
                    TaskList = lib_role_task:get_npc_task_list(NpcId, TaskArgs),
                    {ok, BinData} = pt_121:write(12101, [NpcId, TaskList]),
                    lib_server_send:send_to_sid(Sid, BinData),
                    {ok, NewPs};
                {ok, _Code} ->
                    {ok, NewPs};
                {false, _Code} ->
                    {ok, BinData} = pt_300:write(30004, [0, _Code, []]),
                    lib_server_send:send_to_sid(Sid, BinData),
                    {ok, NewPs}
            end
    end;

%% 放弃任务
handle(30005, Status, [TaskId]) ->
    lib_role_task:abnegate(TaskId, lib_task_api:ps2task_args(Status)),
    {ok,Status};

%% 任务对话事件
handle(30007, Status, [TaskId, NpcId]) ->
    {Type, TalkId} = lib_role_task:get_npc_task_talk_id(TaskId, NpcId, lib_task_api:ps2task_args(Status)),
    case Type of
        link_talk ->
            lib_role_task:event(?TASK_CONTENT_TALK, {id,TalkId,NpcId}, Status#player_status.id);
        _->
            lib_role_task:event(?TASK_CONTENT_TALK, {id,NpcId}, Status#player_status.id)
    end,
    {ok,Status};

%% 探索事件
handle(30008, Status, _) ->
    lib_task_api:reach_place(Status#player_status.id, Status#player_status.scene, Status#player_status.x, Status#player_status.y);

%% 触发赏金任务和联盟周任务
handle(30009, Status, [TaskType]) when TaskType == ?TASK_TYPE_GUILD ->
    #player_status{id = RoleId, sid = Sid, figure = #figure{guild_id = GuildId, lv = RoleLv}} = Status,
    OpenLv = lib_module:get_open_lv(?MOD_TASK,2),
    case data_task_lv_dynamic:get_task_type(TaskType) of
        #task_type{count = Count, module_id = ModuleId, counter_id = CounterId} ->
            FinishCount = lib_daily:get_count(RoleId, ModuleId, CounterId),
            ErrorCode
                = if
                      FinishCount >= Count ->
                            ?ERRCODE(err300_guild_task_finished);
                      GuildId == 0 ->
                            ?ERRCODE(err300_not_guild);
                      RoleLv < OpenLv ->
                            ?ERRCODE(err300_lv_not_enough);
                      true ->
                            lib_role_task:trigger_type_task(TaskType, lib_task_api:ps2task_args(Status)), ok
                  end,
            if
                ErrorCode == ok -> skip;
                true ->
                    {ok, BinData} = pt_300:write(30009, [ErrorCode]),
                    lib_server_send:send_to_sid(Sid, BinData)
            end;
        _ ->
            skip
    end;

%% 任务类型的显示
handle(30010, Status, [TaskType]) when TaskType == ?TASK_TYPE_DAILY; TaskType == ?TASK_TYPE_GUILD ->
    #player_status{id = RoleId, sid = Sid,task_daily=TaskDaily} = Status,
    case data_task_lv_dynamic:get_task_type(TaskType) of
        #task_type{count = Count, module_id = ModuleId, counter_id = CounterId} ->
            #task_daily{dailys=DailyMap}=TaskDaily,
            State = maps:get(TaskType,DailyMap,0),
            FinishCount = lib_daily:get_count(RoleId, ModuleId, CounterId),
            {ok, BinData} = pt_300:write(30010, [TaskType, FinishCount, Count, State]),
            lib_server_send:send_to_sid(Sid, BinData);
        _ ->
            skip
    end,
    {ok,Status};

%% 赏金和公会周任务任务奖励内容
handle(30011, Status, [TaskId]) ->
    TaskArgs = lib_task_api:ps2task_args(Status),
    case data_task:get(TaskId) of
        #task{type = Type} when Type == ?TASK_TYPE_DAILY; Type == ?TASK_TYPE_GUILD ->
          lib_role_task:get_special_task_reward(TaskId, TaskArgs, Type);
        _ ->
          skip
    end,
    {ok,Status};

%% 上一次完成的主线id
handle(30012, Status, _) ->
    #player_status{sid = Sid, last_task_id = LastTaskId} = Status,
    lib_server_send:send_to_sid(Sid, pt_300, 30012, [LastTaskId]);

%% 客户端杀死客户端怪物触发任务数量
%% 选项对话任务触发完成
handle(30015, Status, [ContentType, MonId, TalkId]) ->
    if
        % ContentType == ?TASK_CONTENT_GUILD_EQ_RECYCLE -> %% 特殊帮派装备回收:MonId是物品唯一id
        %     GoodsStatus = lib_goods_do:get_goods_status(),
        %     Res = case lib_goods_check:check_goods_normal(GoodsStatus, MonId) of
        %               {ok, #goods{goods_id=GoodsTypeId, type = Type, color = Color}} ->
        %                   if
        %                       Color =/= ?PURPLE orelse Type =/= ?GOODS_TYPE_EQUIP ->
        %                           ?ERRCODE(err150_fail);
        %                       true ->
        %                           case lib_goods_api:delete_one_by_id(Status, MonId, GoodsTypeId, 1, finish_task) of
        %                               ok ->
        %                                   EquipStage = 0,
        %                                   lib_task_api:guild_eq_recycle(Status, EquipStage, Color),
        %                                   ok;
        %                               _R -> ?ERRCODE(err150_fail)
        %                           end
        %                   end;
        %               _R ->?ERRCODE(err150_no_goods)
        %           end,
        %     ?IF(Res == ok, skip, lib_server_send:send_to_sid(Sid, pt_300, 30015, [Res]));
        % ContentType == ?TASK_CONTENT_KILL ->
        %     lib_task_api:kill_mon(Ps, MonId);
        ContentType == ?TASK_CONTENT_MAILER_RUN->%%送信任务MonId为NpcID
            lib_task_api:finish_mailer_run(Status,MonId);
        ContentType == ?TASK_CONTENT_CHOOSE_TALK->%%选项对话MonId为NpcID
            lib_role_task:event(?TASK_CONTENT_TALK, {id,MonId}, Status#player_status.id),
            lib_task_api:finish_choose_talk(Status,MonId,TalkId);
        MonId == 10000020 orelse MonId == 10020023 ->
            lib_task_api:collect_mon(Status, MonId);
        true ->
            ok
    end,
    {ok,Status};

%%触发长剧情
handle(30016, #player_status{id = RoleId, sid = Sid} = Ps, [TaskId, Type, EndTime]) ->
  Count = lib_counter:get_count(RoleId, ?MOD_TASK, 1, TaskId),
  EventRef = get({lib_task, event_story, TaskId}),
  if
    Count > 0 andalso Type == 1 -> lib_server_send:send_to_sid(Sid, pt_300, 30016, [?FAIL]);
    Type == 1 andalso is_reference(EventRef) == false -> lib_task:event_to_story(Ps, TaskId, EndTime);
    Type == 2 andalso is_reference(EventRef) -> lib_task:event_to_cancel_story(Ps, TaskId);
    true -> ok
  end;

%% 已经完成的任务列表
handle(30017, Status, _) ->
    List = lib_task:get_task_log_id_list(),
    lib_server_send:send_to_sid(Status#player_status.sid, pt_300, 30017, [List]),
    {ok,Status};

%% 使用快速完成任务
handle(30018, Status, [Type]) ->
    #player_status{id=RoleID,figure=#figure{vip=Vip}}=Status,
    Data = ?ERRCODE(err300_task_no_finish),
    TaskId = filter_can_auto_finish(Status,Type),
    case lib_task:get_task_finish_state(TaskId, lib_task_api:ps2task_args(Status)) of
        Data ->
            case data_task:get(TaskId) of
                #task{type=Type}->
                    case data_task_lv_dynamic:get_task_type(Type) of
                         #task_type{finish_cost=Cost}->
                            case finish_task_quick(Status,TaskId,Cost) of
                                {ok,NStatus0}->
                                    NStatus = case Vip>=3 of
                                        true->
                                            case lib_achievement:check_can_free_sweep(Status) of
                                                true when Type == ?TASK_TYPE_DAILY ->
                                                    NStatus0;
                                                _ ->
                                                    Awards = [{?TYPE_BGOLD,?GOODS_ID_BGOLD,1}],
                                                    lib_goods_api:send_reward(NStatus0,Awards,quick_task)
                                            end;
                                        _->
                                            NStatus0
                                    end,
                                    {ok, BinData} = pt_300:write(30018, [?SUCCESS]),
                                    lib_server_send:send_to_uid(RoleID,BinData),
                                    handle(30000, NStatus, ?SUCCESS),
                                    {ok,NStatus};
                                {Err,NStatus}->
                                    {ok, BinData} = pt_300:write(30018, [Err]),
                                    lib_server_send:send_to_uid(RoleID,BinData),
                                    {ok,NStatus}
                            end;
                        _->
                            {ok,Status}
                    end;
                _->
                    {ok,Status}
            end;
        true->%%已完成任务
            {ok, BinData} = pt_300:write(30018, [?ERRCODE(err300_fin)]),
            lib_server_send:send_to_uid(RoleID,BinData),
            {ok,Status};
        _R->
            {ok, BinData} = pt_300:write(30018, [_R]),
            lib_server_send:send_to_uid(RoleID,BinData),
           {ok,Status}
    end;



%%跑环任务 每10环可手动领取一次 没领的邮件补偿
handle(30019,Status,[TaskType]) when TaskType == ?TASK_TYPE_GUILD ->
    #player_status{id = RoleId, sid = Sid,task_daily=TaskDaily0} = Status,
    case data_task_lv_dynamic:get_task_type(TaskType) of
        #task_type{module_id = ModuleId, counter_id = CounterId} ->
            TaskDaily = lib_role_task:fix_task_daily(TaskDaily0),
            #task_daily{dailys=DailyMap}=TaskDaily,
            State = maps:get(TaskType,DailyMap,0),
            FinishCount = lib_daily:get_count(RoleId, ModuleId, CounterId),
            NState = State+1,
            case lib_role_task:check_task_daily(TaskType,NState,FinishCount) of
                {ok,Awards}->
                    Produce = #produce{reward = Awards, type = task_daily_ten},
                    {ok,NStatus0} = lib_goods_api:send_reward_with_mail(Status, Produce,?MOD_TASK),
                    NDailyMap = maps:put(TaskType,NState,DailyMap),
                    NTaskDaily = TaskDaily#task_daily{dailys=NDailyMap},
                    lib_role_task:save_task_daily(RoleId,NTaskDaily),
                    NStatus = NStatus0#player_status{task_daily=NTaskDaily},
                    Res = ?SUCCESS;
                {false,Res}->
                    NStatus = Status
            end,
            {ok,Bin} = pt_300:write(30019,[Res,TaskType,NState]),
            lib_server_send:send_to_sid(Sid,Bin),
            {ok,NStatus};
        _->
            {ok,Status}
    end;

handle(_Cmd, _Ps, _Data) ->
  ?PRINT("~p~n",[_Data]),
    {error, bad_request}.


%% 检查任务的完成状态
check_task_finish_state(Ps, #task{id = TaskId, type = Type}, _SelectItemList, _DoubleType)
  when Type == ?TASK_TYPE_GUILD ->
    #player_status{guild=#status_guild{id=GuildID}}=Ps,
    case lib_task:get_task_finish_state(TaskId, lib_task_api:ps2task_args(Ps)) of
      true when GuildID>0  ->
        {true, [], Ps}; %% 已经完成
      _Error  ->
        %% ?ERR("check task finish state error :~p~n", [_Error]),
        {false, ?FAIL}
  end;
check_task_finish_state(Ps, #task{id = TaskId, type = Type}, _SelectItemList, _DoubleType)
  when Type == ?TASK_TYPE_DAILY; Type == ?TASK_TYPE_GUILD; Type == ?TASK_TYPE_SIDE;Type == ?TASK_TYPE_FOUR ->
    case lib_task:get_task_finish_state(TaskId, lib_task_api:ps2task_args(Ps)) of
      true    ->
        {true, [], Ps}; %% 已经完成
      _Error  ->
        %% ?ERR("check task finish state error :~p~n", [_Error]),
        {false, ?FAIL}
  end;
check_task_finish_state(Ps, #task{id = TaskId, type = ?TASK_TYPE_TURN, end_item = CostList}, _SelectItemList, _DoubleType) -> %% 转生需要扣除物品
    if
      CostList == [] -> {true, [], Ps};
      true ->
        case lib_task:get_task_finish_state(TaskId, lib_task_api:ps2task_args(Ps)) of
          true ->
            case lib_goods_api:check_object_list(Ps, CostList) of
              true ->
                case lib_goods_api:cost_object_list(Ps, CostList, finish_task, "") of
                  {true, NewPs} -> {true, [], NewPs};
                  {false, ErrCode, _NewPs} -> {false, ErrCode}
                end;
              {false, ErrCode} -> {false, ErrCode}
            end;
          _Error ->
            ?ERR("check task finish state error :~p~n", [_Error]),
            {false, ?FAIL}
        end
    end;
check_task_finish_state(Ps, #task{id = TaskId, type = ?TASK_TYPE_NUCLEON, end_item = CostList}, _SelectItemList, _DoubleType) -> %% 转生需要扣除物品
    if
      CostList == [] -> {true, [], Ps};
      true ->
        case lib_task:get_task_finish_state(TaskId, lib_task_api:ps2task_args(Ps)) of
          true ->
            case lib_goods_api:check_object_list(Ps, CostList) of
              true ->
                case lib_goods_api:cost_object_list(Ps, CostList, finish_task, "") of
                  {true, NewPs} -> {true, [], NewPs};
                  {false, ErrCode, _NewPs} -> {false, ErrCode}
                end;
              {false, ErrCode} -> {false, ErrCode}
            end;
          _Error ->
            ?ERR("check task finish state error :~p~n", [_Error]),
            {false, ?FAIL}
        end
    end;
check_task_finish_state(Ps, #task{type = ?TASK_TYPE_MAIN} = TD, _SelectItemList, DoubleType) -> %% 主线任务判断双倍奖励
    case check_task_double(Ps, DoubleType, TD) of
      {true, DoubleCost, NewPs} when DoubleCost > 0 -> {true, [{double_type, ?DOUBLE_TYPE}], NewPs};
      {true, _DoubleCost, NewPs} -> {true, [], NewPs};
      {false, ErrCode} -> {false, ErrCode}
    end;
check_task_finish_state(_Ps, #task{id = TaskId}, _SelectItemList, _DoubleType) ->
    ?ERR("check task error id:~p~n", [TaskId]),
    {false, ?FAIL}.

%%检测双倍奖励
check_task_double(Ps, ?DOUBLE_TYPE, #task{double_cost = DoubleCost}) when DoubleCost > 0 ->
  case lib_goods_api:cost_object_list_with_check(Ps, [{?TYPE_BGOLD, 0, DoubleCost}], task_double, "task_double") of
    {true, NewPs,_} -> {true, DoubleCost, NewPs};
    {false, ErrCode, _NewPs} -> {false, ErrCode}
  end;
check_task_double(_Ps, ?DOUBLE_TYPE, _TD) ->
  {false, ?ERRCODE(err300_not_double_reward)};
check_task_double(Ps, 0, _TD) -> {true, 0, Ps}.



%% 快速完成任务
finish_task_quick(Status,TaskId, Cost) ->
    TaskArgs = lib_task_api:ps2task_args(Status),
    TD = lib_task:get_data(TaskId),
    %% 达成成就等级可以免费扫荡
    case lib_achievement:check_can_free_sweep(Status) of
        true when TD#task.type == ?TASK_TYPE_DAILY ->
            case lib_role_task:finish(TaskId, cost_finish, TaskArgs) of
                true ->
                    {ok, Status};
                {ok, _Res} ->
                    {ok, Status};
                {false, Res} ->
                    {Res, Status}
            end;
        _ ->
            case lib_goods_api:cost_object_list_with_check(Status, Cost, quick_task, "") of
                {true,NStatus,_}->
                    case lib_role_task:finish(TaskId, cost_finish, TaskArgs) of
                        true ->
                            {ok, NStatus};
                        {ok, _Code} ->
                            {ok, NStatus};
                        {false, Code} ->
                            {Code,lib_goods_api:send_reward(NStatus,Cost, quick_task)}
                    end;
                _->
                    {?GOLD_NOT_ENOUGH,Status}
            end
    end.


%%可接列表查找 有就自动接
%%可接没有 已接查找
filter_can_auto_finish(Status,TaskType)->
    #player_status{id = RoleID, figure = #figure{guild_id = GuildId, lv = RoleLv}} = Status,
    case lib_task:get_task_bag_id_list_type(TaskType) of
        [H|_T]->
            H#role_task.task_id;
        _-> %%没有已接 触发一次
             OpenLv = case TaskType of
                ?TASK_TYPE_DAILY->
                    lib_module:get_open_lv(?MOD_TASK,1);
                _->
                    lib_module:get_open_lv(?MOD_TASK,2)
            end,
            case data_task_lv_dynamic:get_task_type(TaskType) of
                #task_type{count = Count, module_id = ModuleId, counter_id = CounterId} ->
                    FinishCount = lib_daily:get_count(RoleID, ModuleId, CounterId),
                    ErrorCode
                        = if
                            FinishCount >= Count ->
                                0;
                            TaskType == ?TASK_TYPE_GUILD andalso GuildId == 0 ->
                                0;
                            TaskType==?TASK_TYPE_DAILY andalso RoleLv < OpenLv ->
                                0;
                            TaskType == ?TASK_TYPE_GUILD andalso RoleLv < OpenLv ->
                                0;
                            true ->
                                lib_role_task:trigger_type_task(TaskType, lib_task_api:ps2task_args(Status)),
                                ok
                        end,
                    case ErrorCode of
                        ok->
                            case lib_task:get_task_bag_id_list_type(TaskType) of
                                [H|_T]->
                                    H#role_task.task_id;
                                _->
                                    0
                            end;
                        _->
                            0
                    end;
                _->
                    0
            end
    end.


