%%-----------------------------------------------------------------------------
%% @Module  :       mod_boss_first_blood
%% @Author  :       liushl
%% @Created :       2021-04-28
%% @Description:    boss首杀
%%-----------------------------------------------------------------------------
-module(boss_first_blood).

-include("common.hrl").
-include("errcode.hrl").
-include("equipment_check.hrl").
-include("predefine.hrl").
-include("def_module.hrl").
-behaviour(gen_server).

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

-export([
    first_blood_info/2,
    get_server_award/2,
    rename/2,
    
    boss_dead/4
]).

%%-----------------------------------------------------------------------------
%% @doc 玩家协议交互
%%-----------------------------------------------------------------------------
%% 查看BOSS信息
first_blood_info(Sid, AwardInfo) ->
    gen_server:cast(?MODULE, {first_blood_info, Sid, AwardInfo}).

%% 领奖
get_server_award(Pid, BossId) ->
    gen_server:cast(?MODULE, {get_server_award, Pid, BossId}).

%% 玩家改名
rename(RoleId, Name) ->
    gen_server:cast(?MODULE, {rename, RoleId, Name}).
%%-----------------------------------------------------------------------------
%% @doc 系统消息
%%-----------------------------------------------------------------------------
%% BOSS被击杀
boss_dead(BossId, BossName, BossLv, Killers) ->
    case data_equipment_check:get_boss_first_blood(BossId) of
        #base_boss_first_blood{} ->
            gen_server:cast(?MODULE, {boss_dead, BossId, BossName, BossLv, Killers});
        _ ->
            ignore
    end.

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

init([]) ->
    erlang:send_after(3000, self(), init),
    {ok, #boss_first_blood{}}.

handle_cast(Msg, State) ->
    case catch do_handle_cast(Msg, State) of
        {ok, NewState} when is_record(NewState, boss_first_blood) ->
            {noreply, NewState};
        Err ->
            ?ERR("handle_cast Msg:~p error:~p~n", [Msg, Err]),
            {noreply, State}
    end.

%% BOSS被击杀
do_handle_cast({boss_dead, BossId, BossName, BossLv, Killers}, #boss_first_blood{boss_info = BossInfo} = State) ->
    case lists:keymember(BossId, #boss_info.boss_id, BossInfo) of
        true  ->
            {ok, State};
        false ->
            case data_equipment_check:get_boss_first_blood(BossId) of
                #base_boss_first_blood{server_first_award = Award} ->
                    Time = utime:unixtime(),
                    Names = get_killers_names(Killers),
                    Boss = #boss_info{
                        boss_id     = BossId,      %% BOSS
                        killers     = Killers,      %% 击杀者
                        names       = Names,        %% 名字
                        time        = Time         %% 时间
                    },
                    db_save_boss_info(Boss),
                    %% 给每一个首杀者都发一封邮件
                    Roles = [Id || {Id, _} <- Killers],
                    lib_mail_api:send_sys_mail(Roles, utext:get(1450001), utext:get(1450002, [BossLv, BossName]), Award),
                    
                    lib_chat:send_TV({all}, ?MOD_EQUIP_CHECK, 1, [Names, BossLv, BossName]),
                    
                    {ok, Bin} = pt_145:write(14502, [2, BossId]),
                    lib_server_send:send_to_all(Bin),
                    
                    {ok, State#boss_first_blood{boss_info = [Boss|BossInfo]}};
                _ ->
                    {ok, State}
            end
    end;
%% 查看基本信息
do_handle_cast({first_blood_info, Sid, AwardInfo}, #boss_first_blood{boss_info = BossInfo} = State) ->
    Info =
        [
            begin
                KillerId =
                    case Killers of
                        [{Id, _}] ->
                            Id;
                        _ -> 0
                    end,
                case lists:keyfind(BossId, #role_boss_first_blood.boss_id, AwardInfo) of
                    #role_boss_first_blood{
                        self_award = SelfAward,
                        server_award = ServerAward
                    } ->
                        {BossId, Names, KillerId, Time, SelfAward, ServerAward};
                    _ ->
                        {BossId, Names, KillerId, Time, 0, 0}
                end
            end
            || #boss_info{
                    boss_id     = BossId,        %% BOSS
                    names       = Names,          %% 名字
                    killers     = Killers,
                    time        = Time
                } <- BossInfo
        ],
    {ok, Bin} = pt_145:write(14501, [Info]),
    lib_server_send:send_to_sid(Sid, Bin),
    {ok, State};

%% 领取全服奖励
do_handle_cast({get_server_award, Pid, BossId}, #boss_first_blood{boss_info = BossInfo} = State) ->
    IsFirstKilled = lists:keymember(BossId, #boss_info.boss_id, BossInfo),
    lib_player:apply_cast(
        Pid,
        ?APPLY_CAST_STATUS,
        boss_first_blood_logic,
        get_server_award_callback,
        [BossId, IsFirstKilled]
    ),
    {ok, State};

%% 玩家修改名字
do_handle_cast({rename, RoleId, Name}, #boss_first_blood{boss_info = BossInfo} = State) ->
    NewBossInfo =
    [
        case lists:keymember(RoleId, 1, Boss#boss_info.killers) of
            true  ->
                NewKillers = lists:keystore(RoleId, 1, Boss#boss_info.killers, {RoleId, Name}),
                NewBoss = Boss#boss_info{killers = NewKillers, names = get_killers_names(NewKillers)},
                db_save_boss_info(NewBoss),
                NewBoss;
            false ->
                Boss
        end
        || Boss <- BossInfo
    ],
    {ok, State#boss_first_blood{boss_info = NewBossInfo}};

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

handle_info(Info, State) ->
    case catch do_handle_info(Info, State) of
        {ok, NewState} when is_record(NewState, boss_first_blood) ->
            {noreply, NewState};
        Err ->
            ?ERR("handle_info Info:~p error:~p~n", [Info, Err]),
            {noreply, State}
    end.

do_handle_info(init, _State) ->
    AllBossInfo = db:get_all(?SQL_GET_BOSS_INFO),
    BossInfo =
        [
            begin
                Killers = util:bitstring_to_term(KillersBin),
                #boss_info{
                    boss_id     = BossId,      %% BOSS
                    killers     = Killers,      %% 击杀者
                    names       = get_killers_names(Killers),        %% 名字
                    time        = Time         %% 时间
                }
            end
            || [BossId, KillersBin, Time] <- AllBossInfo
        ],
    {ok, #boss_first_blood{boss_info = BossInfo}};

do_handle_info(_Info, State) ->
    {ok, State}.

handle_call(Request, _From, State) ->
    case catch do_handle_call(Request, State) of
        {ok, Reply} ->
            {reply, Reply, State};
        Err ->
            ?ERR("handle_call Request:~p error:~p~n", [Request, Err]),
            {noreply, State}
    end.

do_handle_call(_Request, _State) -> {ok, ok}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.


get_killers_names(Roles) ->
    NameList =
        lists:foldl(
            fun({_Id, Name}, Temp) ->
                Temp ++ [unicode:characters_to_list(Name)]
            end, [], Roles
        ),
    string:join(NameList, "、").

db_save_boss_info(Boss) ->
    #boss_info{
        boss_id     = BossId,      %% BOSS
        killers     = Killers,     %% 击杀者
        time        = Time         %% 时间
    } = Boss,
    SQL = io_lib:format(?SQL_SAVE_BOSS_INFO, [BossId, util:term_to_bitstring(Killers), Time]),
    db:execute(SQL).