%% ---------------------------------------------------------------------------
%% @doc lib_role_task
%% @author zmh
%% @since  2018-04-27
%% @deprecated  玩家任务
%% ---------------------------------------------------------------------------
-module(lib_role_task).
-export([login/1]).
-compile(export_all).

-include("common.hrl").
-include("server.hrl").
-include("task.hrl").
-include("figure.hrl").
-include("def_module.hrl").
-include("daily.hrl").
-include("def_fun.hrl").
-include("def_event.hrl").
-include("rec_event.hrl").
-include("predefine.hrl").
-include("scene.hrl").
-include("errcode.hrl").
-include("goods.hrl").


login(TaskArgs)->
    #task_args{id=RoleID}=TaskArgs,
	lib_task:flush_role_task(TaskArgs),
    load_task_daily(RoleID).

%% ================================= call =================================
%% 获取任务的是否完成
get_task_finish_state(TaskId, TaskArgs)->
	lib_task:get_task_finish_state(TaskId, TaskArgs).


%% 强制触发任务
force_trigger(TaskId, TaskArgs)->
	lib_task:force_trigger(TaskId, TaskArgs).


%% 强制移除任务
del_task(TaskId, TaskArgs)->
	lib_task:del_task(TaskId,TaskArgs).

%% npc任务状态
get_npc_state(NpcId, Status) ->
	lib_task:get_npc_state(NpcId, Status).

%% 获取npc任务
get_npc_task_list(NpcId, TaskArgs)->
	lib_task:get_npc_task_list(NpcId, TaskArgs).

%% 获取当前npc任务对话
get_npc_task_talk_id(TaskId, NpcId, TaskArgs)->
	lib_task:get_npc_task_talk_id(TaskId, NpcId, TaskArgs).

%% 检查物品是否为任务需要
can_gain_item() ->
	lib_task:can_gain_item().

%% 触发任务
trigger(TaskId, TaskArgs)->
	lib_task:trigger(TaskId, TaskArgs).

%% 放弃任务
abnegate(TaskId, TaskArgs)->
	lib_task:abnegate(TaskId, TaskArgs).

%% 完成任务并且获得奖励
finish(TaskId, ParamList, TaskArgs)->
    case lib_task:finish(TaskId, ParamList, TaskArgs) of
        {false, ReasonCode} ->
            {false, ReasonCode};
        Result ->
	        #task_args{id = RoleId} = TaskArgs,
            %% 派发完成任务事件
            #task{type = TaskType} = data_task:get(TaskId),
            lib_task:after_finish_round_task(RoleId, TaskType, 1),
            lib_player_event:async_dispatch(RoleId, ?EVENT_FINISH_TASK, TaskId),
            Result
    end.

%%是否处于指定任务中  接取状态
is_during_task(TaskId)->
    lib_task:is_during_task(TaskId).

%% 是否完成某个任务
is_finish_task_id(TaskId) ->
    lib_task:is_finish_task_id(TaskId).

%% 是否完成某章节的所有主线任务
is_finish_chapter_all_task(Chapter)->
	lib_task:is_finish_chapter_all_task(Chapter).

%% 获取玩家自己的任务列表
get_my_task_list(TaskArgs)->
	lib_task:get_my_task_list(TaskArgs).

%% 刷线npc
refresh_npc_ico(TaskArgs)->
	lib_task:refresh_npc_ico(TaskArgs).


%% 完成任务过程 默认玩家进程内调用
event(Event, Params, RoleID)->
    event(Event, Params, RoleID,true).
event(Event, Params, RoleID,true)->
    lib_task:action(RoleID, Event, Params);
event(Event, Params, RoleID,_)->
    lib_player:apply_cast(RoleID, ?APPLY_CAST, ?MODULE, event, [Event, Params, RoleID]).


%% 玩家升级触发任务
lv_up(TaskArgs) ->
    lib_task:lv_up(TaskArgs).

%% 获取任务奖励
get_special_task_reward(TaskId, TaskArgs, Type)->
    lib_task:get_special_task_reward(TaskId, Type, TaskArgs).

%% 清理可接任务
gm_refresh_task(GmType, TaskArgs) ->
    lib_task:gm_refresh_task(GmType, TaskArgs).

% %% 每日清理
% each_daily_clear(TaskArgs, ?TWELVE) ->
%     zero_task_clear(TaskArgs);
each_daily_clear(TaskArgs, ?FOUR) ->
    daily_task_clear(TaskArgs);
each_daily_clear(_, _) ->
    ok.

daily_task_clear(TaskArgs) ->
    Data = get(),
    [erase(Key)|| {Key, Value} <- Data, is_record(Value, role_task_log),
        lists:member(Value#role_task_log.type,[?TASK_TYPE_DAILY,?TASK_TYPE_GUILD,?TASK_TYPE_FOUR])],

    lib_task:refresh_trigger_by_type(TaskArgs, ?TASK_TYPE_FOUR),

    lib_task:refresh_active(TaskArgs),
    #task_type{count=DCount} = data_task_lv_dynamic:get_task_type(?TASK_TYPE_DAILY),
    {ok,Bin0} = pt_300:write(30010,[7,0,DCount,0]),
    % {ok,Bin1} = pt_300:write(30010,[5,0,10]),
    #task_type{count=GCount} = data_task_lv_dynamic:get_task_type(?TASK_TYPE_GUILD),
    {ok,Bin2} = pt_300:write(30010,[6,0,GCount,0]),
    Bin  = <<Bin0/binary,Bin2/binary>>,
    lib_server_send:send_to_sid(TaskArgs#task_args.sid,Bin),

    lib_task:refresh_trigger_by_type(TaskArgs, ?TASK_TYPE_DAILY),
    % lib_task:refresh_trigger_by_type(TaskArgs, ?TASK_TYPE_CROSS),
    lib_task:refresh_trigger_by_type(TaskArgs, ?TASK_TYPE_GUILD),

    lib_task:auto_trigger(?TASK_TYPE_FOUR,TaskArgs),

    lib_task:refresh_npc_ico(TaskArgs),
    lib_task:get_my_task_list(TaskArgs),

    Figure = TaskArgs#task_args.figure,
    Lv = Figure#figure.lv,
    case data_task:get(3070002) of
        #task{level=L} when Lv>=L->
            lib_task:force_trigger(3070002, TaskArgs);
        _->
            ignore
    end,
    auto_trigger_daily_task(TaskArgs),
    ok.
% zero_task_clear(TaskArgs) ->
%     %% 清理缓存中已接 每日刷新任务
%     lib_task:delete_task_bag_list_by_type(?TASK_TYPE_ZERO),
%     %% 清理缓存中已完成 每日刷新任务
%     lib_task:delete_task_log_by_type(?TASK_TYPE_ZERO),

%     lib_task:refresh_active(TaskArgs),
%     %% 周一0点清理公会任务

%     AllTask = lib_task:get_task_bag_id_list(),
%     NewAllTask =  case util:get_open_day()>=30 of
%         true->
%             lib_task:fix_task_npc(AllTask,[],TaskArgs);
%         _->
%             AllTask
%     end,
%     lib_task:set_task_bag_list(NewAllTask),

%     %% 自动接取任务
%     lib_task:auto_trigger(TaskArgs),
%     lib_task:refresh_npc_ico(TaskArgs),
%     lib_task:get_my_task_list(TaskArgs),
%     ok.
%% 触发赏金任务和公会周任务
trigger_type_task(TaskType, TaskArgs)->
    {_, Code} = lib_task:trigger_type_task(TaskType, TaskArgs),
    {ok, Bin} = pt_300:write(30009, [Code]),
    lib_server_send:send_to_uid(TaskArgs#task_args.id, Bin),
    ok.

%% 任务物品掉落
send_drop_goods(RoleID,MonId,Goods)->
    TaskGoods = lib_task:can_gain_item(),
    drop_logic:filter_task_goods(RoleID, MonId, TaskGoods, Goods).

%%下线
logout()->
    case lib_task:get_task_bag_id_list() of
        undefined ->
        	skip;
        [] ->
        	skip;
        RoleTaskList ->
        	lib_task:task_offline_up(RoleTaskList)
    end.

%%数据跨天校正
fix_task_daily(TaskDaily)->
    #task_daily{time=LTime}=TaskDaily,
    case utime:is_logic_same_day(LTime) of
        true->
            TaskDaily;
        _->
            #task_daily{dailys=#{},time=utime:unixtime()}
    end.

save_task_daily(RoleId,TaskDaily)->
    #task_daily{
        dailys = DailyMap,
        time = Time
    }=TaskDaily,
    Dailys0 = maps:to_list(DailyMap),
    Dailys  =  util:term_to_string(Dailys0),
    Sql = io_lib:format(?SQL_ROLE_TASK_DAILY_INS,[RoleId,Dailys,Time]),
    db:execute(Sql).

load_task_daily(RoleID)->
    Sql = io_lib:format(?SQL_ROLE_DAILY_GET, [RoleID]),
    case db:get_row(Sql) of
        [Dailys0,Time]->
            case utime:is_logic_same_day(Time) of
                true->
                    Dailys = util:bitstring_to_term(Dailys0),
                    DailyMap = maps:from_list(Dailys),
                    #task_daily{dailys=DailyMap,time=Time};
                _->
                    #task_daily{dailys=#{},time=utime:unixtime()}
            end;
        _->
            #task_daily{dailys=#{},time=utime:unixtime()}
    end.

check_delay_mail(RoleID,TaskDaily)->
    #task_daily{dailys=DailyMap,time=Time}=TaskDaily,
    case utime:is_logic_same_day(Time) of
        true->
            skip;
        _->
            Awards = delay_mail([?TASK_TYPE_GUILD,?TASK_TYPE_DAILY],RoleID,DailyMap,[]),
            Produce = #produce{reward = Awards, type = task_daily_ten},
            Awards/=[] andalso lib_goods_api:send_reward_with_mail(RoleID, Produce,?MOD_TASK)
    end.

delay_mail([],_,_,Awards)->
    util:combine_list(Awards,1);
delay_mail([H|T],RoleID,DailyMap,Awards)->
    case data_task_lv_dynamic:get_task_type(H) of
        #task_type{module_id = ModuleId, counter_id = CounterId} ->
            State = maps:get(H,DailyMap,0),
            FinishCount = lib_daily:get_count(RoleID, ModuleId, CounterId),
            NAwards = calc_delay_awards(H,State+1,FinishCount,Awards),
            delay_mail(T,RoleID,DailyMap,NAwards);
        _->
            delay_mail(T,RoleID,DailyMap,Awards)
    end.

check_task_daily(TaskType,State,FinishCount)->
    case data_task_lv_dynamic:get_task_daily(TaskType,State) of
        #base_task_daily{awards=Awards,counts=NeedC}->
            case FinishCount>=NeedC of
                true->
                    {ok,Awards};
                _->
                    {false,?ERRCODE(err300_need_finish_more_task)}
            end;
        _->
            {false,?ERRCODE(missing_config)}
    end.

calc_delay_awards(Type,State,FinishCount,Awards)->
    case check_task_daily(Type,State,FinishCount) of
        {ok,Adds}->
            calc_delay_awards(Type,State+1,FinishCount,Adds++Awards);
        _->
            Awards
    end.

%% 处理玩家事件
handle_event(Status, #event_callback{type_id = ?EVENT_FOUR_CLOCK})->
    #player_status{id=RoleID}=Status,
    NTaskDaily = #task_daily{dailys=#{},time=utime:unixtime()},
    save_task_daily(RoleID,NTaskDaily),
    NStatus = Status#player_status{task_daily=NTaskDaily},
    {ok, NStatus};
handle_event(Status, #event_callback{type_id = ?EVENT_LOGIN_CAST})->
    #player_status{id=RoleID,task_daily=TaskDaily}=Status,
    check_delay_mail(RoleID,TaskDaily),
    NTaskDaily = fix_task_daily(TaskDaily),
    NStatus = Status#player_status{task_daily=NTaskDaily},
    {ok, NStatus};
 %% 进阶系统进阶事件
handle_event(Status, #event_callback{type_id = ?EVENT_FOSTER_GRADE_UP,data={Type,Grade}}) ->
    lib_task_api:foster_grade_up(Status,Type,Grade),
    {ok, Status};
handle_event(Status, _) ->
    {ok, Status}.

%%工具接口 用以查询辅助调试%%
debug(RoleID,OpTy)->
    lib_player:apply_cast(RoleID, ?APPLY_CAST, ?MODULE, debug_task, [OpTy]).
debug_task(0)-> %%打印已接任务
    TaskLists = lib_task:get_task_bag_id_list(),
    ?INFO("BagTasks:~p~n",[TaskLists]),
    ok;
debug_task(1)->%%打印所有已完成
    Data = get(),
    Finishs = [Value|| {_Key, Value} <- Data, is_record(Value, role_task_log)],
    ?INFO("FinishTasks:~p~n",[Finishs]),
    ok;
debug_task(2)->%%打印可接任务
    TaskLists = lib_task:get_query_cache_list(),
    ?INFO("QueryTasks:~p~n",[TaskLists]),
    ok;
debug_task([0,Type])->%%打印指定已接类型 type区分
    Tasks = lib_task:get_task_bag_id_list_type(Type),
    ?INFO("TypeTasks:~p~n",[Tasks]),
    ok;
debug_task([1,Kind])->%%打印指定已接类型 kind区分
    Tasks = lib_task:get_task_bag_id_list_kind(Kind),
    ?INFO("KindTasks:~p~n",[Tasks]),
    ok;
debug_task([2,TaskID])-> %%指定已接任务
    Value = lib_task:get_task_bag_id_list_task_id(TaskID),
    ?INFO("BagTask:~p~n",[Value]),
    ok;
debug_task([3,TaskID])-> %%指定可接任务
    Value = lib_task:find_query_cache_list(TaskID),
    ?INFO("QueryTasks:~p~n",[Value]),
    ok;
debug_task(_)->ok.



%%npc交换 需要满足开服天数和跨服环境达成
exchange_npc(NpcId)->
    NewNpc = case data_npc:get(NpcId) of
        #ets_npc{target=T} when T > NpcId -> %%Npc升级跨服
            case czone_api:zone_enter_check_city() of
                false->
                    NpcId;
                _->
                    T
            end;
        #ets_npc{target=T} when T < NpcId andalso T>0 -> %%Npc降级本服
            case czone_api:zone_enter_check_city() of
                false->
                    T;
                _->
                    NpcId
            end;
        _->
            NpcId
    end,
    NewNpc.


%%自动接日常任务
auto_trigger_daily_task(TaskArgs)->
    #task_args{
        id=RoleId,
        figure=#figure{lv=RoleLv}
    }=TaskArgs,
    TaskType = ?TASK_TYPE_DAILY,
    OpenLv = lib_module:get_open_lv(?MOD_TASK,1),
    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),
            if
                FinishCount >= Count -> %%尚有未完成
                    skip;
                RoleLv<OpenLv->
                    skip;
                true->
                    case lib_task:get_task_bag_id_list_type(TaskType) of
                        []->
                            lib_role_task:trigger_type_task(TaskType, TaskArgs);
                        _->
                            skip
                    end
            end;
        _->
            skip
    end.


