%% --------------------------------
%% module   :local_legion_mgr.erl
%% desc     :本地指挥室保存
%% author   :zmh
%% time     :21/01/25
%% --------------------------------

-module (local_legion_mgr).

-behaviour (gen_server).

-export ([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-export ([
    start_link/0
    ]).

-export([
    get_history_director/2,
    load_history_logs/0,
    director_log/1  %%新一期任命
    ]).

-include("kf_legion.hrl").
-include("figure.hrl").
-include("def_fun.hrl").
-include("czone.hrl").
-include("common.hrl").
-include("errcode.hrl").


start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

get_history_director(OpTy,RoleID)->
    gen_server:cast(?MODULE,{get_history_director,OpTy,RoleID}).

director_log(ZoneRoles)->
    Zone = czone_api:env_get_zone_id(),
    Fact = czone_api:env_get_faction(),
    case lists:keyfind(Zone,1,ZoneRoles) of
        {_,FactRoles}->
            case lists:keyfind(Fact,1,FactRoles) of
                {_,Roles} when Roles /= [] ->
                    gen_server:cast(?MODULE,{director_log,Roles});
                _->
                    ok
            end;
        _->
            ok
    end.

init(_) ->
    erlang:send_after(500, self(),init_log),
    {ok,[]}.


handle_call(Msg, From, State) ->
    try
        do_handle_call(Msg, From, State)
    catch _:_Error ->
        io:format("do_handle_call Msg:~p, Error:~p, ~p~n", [Msg, _Error, erlang:get_stacktrace()]),
        {reply, error, State}
    end.

handle_cast(Msg, State) ->
    try
        do_handle_cast(Msg, State)
    catch _:_Error ->
        io:format("handle_cast Msg:~p, Error:~p, ~p~n", [Msg, _Error, erlang:get_stacktrace()]),
        {noreply, State}
    end.

handle_info(Msg, State) ->
    try
        do_handle_info(Msg, State)
    catch _:_Error ->
        io:format("handle_info Msg:~p~n Error:~p~n ~p~n", [Msg, _Error, erlang:get_stacktrace()]),
        {noreply, State}
    end.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, _State, _Extra) ->
    ok.


do_handle_call(_Msg, _From, State) ->
    {reply, ok, State}.

do_handle_cast({get_history_director,OpTy,RoleID},HistoryLogs)->
    DataList = lib_role_legion:pack_history_director(OpTy,HistoryLogs,[]),
    {ok,Bin} = pt_603:write(60312,[OpTy,DataList]),
    lib_server_send:send_to_uid(RoleID,Bin),
    {noreply,HistoryLogs};

do_handle_cast({director_log,TmpRoles},HistoryLogs)->
    Time = utime:unixdate(),
    Monday = Time-86400*(utime:day_of_week()-1),  %%周一时间
    SerNum = config:get_server_num(),
    Roles = [#history_role{id=Rid,pos=Pos,time=Time,figure=Figure}||#director_role{rid=Rid,pos=Pos,figure=Figure}<-TmpRoles],
    SerLogs = case lists:keyfind(Monday,#time_history.time,HistoryLogs) of
        #time_history{servers=ServerLogs}->
            SerLog = case lists:keyfind(SerNum,#server_log.server_num,ServerLogs) of
                #server_log{logs=Logs}->
                    NLogs = update_logs(Logs,Roles),
                    #server_log{server_num=SerNum,logs=NLogs};
                _->
                    #server_log{server_num=SerNum,logs=Roles}
            end,
            batch_save_logs(Monday,SerNum,SerLog#server_log.logs),
            lists:keystore(SerNum,#server_log.server_num,ServerLogs,SerLog);
        _->
            batch_save_logs(Monday,SerNum,Roles),
            [#server_log{server_num=SerNum,logs=Roles}]
    end,
    TimeHis = #time_history{time=Monday,servers=SerLogs},
    NHistoryLogs = lists:keystore(Monday,#time_history.time,HistoryLogs,TimeHis),
    {noreply,NHistoryLogs};

do_handle_cast(_Msg, State) ->
    {noreply, State}.


do_handle_info(init_log,_State)->
    NState = load_history_logs(),
    {noreply,NState};

do_handle_info(_Msg, State) ->
    {noreply, State}.


update_logs(Logs,[])->
    Logs;
update_logs(Logs,[H|T])->
    #history_role{pos=Pos}=H,
    NLogs = lists:keystore(Pos,#history_role.pos,Logs,H),
    update_logs(NLogs,T).

batch_save_logs(Time,SerNum,Logs)->
    Sql = ?SQL_LEGION_DIRLOG_BATCH,
    DbList = format_log_roles([],Time,SerNum,Logs),
    batch_save(Sql,DbList).

batch_save(_Sql,[])->
    ok;
batch_save(Sql,DbList)->
    ArgsString = string:join(DbList, ","),
    SqlN = io_lib:format(Sql, [ArgsString]),
    db:execute(SqlN),
    ok.

format_log_roles(DbList,_,_, []) ->
    DbList;
format_log_roles(DbList, Time,SerNum,[Log | T]) ->
    DbLog = format_log_role(Time,SerNum,Log),
    DbRList2 = [DbLog | DbList],
    format_log_roles(DbRList2, Time,SerNum, T).

format_log_role(Issue,SerNum,Log)->
    #history_role{
        id = Rid,
        pos = Pos,
        time = Time,
        figure = Figure
    } = Log,
    #figure{
        name = Name,
        sex = Sex,
        career = Career,
        turn = Turn,
        vip = Vip,
        sup_vip = SVip,
        lv = Lv,
        profile_photo_id = PhoId,
        dress_list = DressList0
    }=Figure,
    DressList1 = [{K,V}||{K,V}<-DressList0,K=:=2],
    DressList = util:term_to_string(DressList1),
    Data = [
        Issue,SerNum,Pos,Rid,Name,Sex,Career,Lv,Turn,Vip,SVip,DressList,PhoId,Time
    ],
    io_lib:format("(~p,~p,~p,~p,'~ts',~p,~p,~p,~p,~p,~p,'~ts',~p,~p)", Data).


%%加载数据
load_history_logs()->
    %%z只要三个月内的数据
    Time = utime:unixtime()-10368000,
    Sql = io_lib:format(?SQL_LEGION_DIRLOG_GET,[Time]),
    case db:get_all(Sql) of
        DataList when is_list(DataList) andalso DataList =/= []->
            init_history_log(DataList,[]);
        _->
            []
    end.

init_history_log([],HistoryLogs)->
    HistoryLogs;
init_history_log([[Issue,SerNum,Pos,Rid,Name,Sex,Career,Lv,Turn,Vip,SVip,DressList0,PhoId,Time]|T],HistoryLogs)->
    Figure = #figure{
        id = Rid,
        name = Name,
        sex = Sex,
        career = Career,
        turn = Turn,
        lv = Lv,
        vip = Vip,
        sup_vip = SVip,
        dress_list = util:bitstring_to_term(DressList0),
        profile_photo_id = PhoId
    },
    Log = #history_role{id=Rid,pos=Pos,time=Time,figure=Figure},
    NHistoryLogs = case lists:keytake(Issue, #time_history.time, HistoryLogs) of
        {value, #time_history{servers=ServerLogs}, LessTimeHis} ->
            case lists:keytake(SerNum,#server_log.server_num,ServerLogs) of
                {value,#server_log{logs=Logs},LessSerLogs}->
                    NLogs = lists:keystore(Pos,#history_role.pos,Logs,Log),
                    SerLog = #server_log{server_num=SerNum,logs=NLogs},
                    SerLogs = [SerLog|LessSerLogs];
                _->
                    SerLog = #server_log{server_num=SerNum,logs=[Log]},
                    SerLogs = [SerLog|ServerLogs]
            end,
            [#time_history{time=Issue,servers=SerLogs}|LessTimeHis];
        _ ->
            SerLog = #server_log{server_num=SerNum,logs=[Log]},
            [#time_history{time=Issue,servers=[SerLog]}|HistoryLogs]
    end,
    init_history_log(T,NHistoryLogs).
