%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     rr("../include/*.hrl"),sys:get_state(beauty_contest).
%%% sys:get_state(beauty_contest_center). utime:unixtime_to_localtime(1600098900).
%%% sys:get_state(beauty_contest_local).
%%% @end
%%%-------------------------------------------------------------------
-module(beauty_contest_api).
-author("liushl").

-include("server.hrl").
-include("figure.hrl").
-include("fashion.hrl").
-include("role_foster.hrl").
-include("beauty_contest.hrl").
-include("def_event.hrl").
-include("rec_event.hrl").
-include("def_module.hrl").
-include("predefine.hrl").
-include("common.hrl").
%% API
-export([
    login/1
    , handle_event/2
    , statistics_contest_data/1
    , check_contest_data/2
]).

-export([
    %% 投票成功
    after_vote/3
    , vote_success/2
    %% 结算发奖
    , settlement/2
    , send_settlement_mail/2
    %% 通知玩家活动结束
    , act_end_notice_role/0
    , role_logic_act_end/1

    , pack_vote_candidate/1
]).
%% 登陆加载投票记录
login(_RoleId) ->
    #role_beauty_contest{}.
%%%-------------------------------------------------------------------
%%% @doc
%%%     玩家数据更新
%%% @end
%%%-------------------------------------------------------------------
%% 角色改名
handle_event(Player, #event_callback{type_id = ?EVENT_RENAME, data = Name}) ->
    beauty_contest:update_role_info(Player#player_status.id, name, Name),
    {ok, Player};
%% 角色VIP升级
handle_event(Player, #event_callback{type_id = ?EVENT_VIP}) ->
    #player_status{id = RoleId, figure = #figure{vip = Vip}} = Player,
    beauty_contest:update_role_info(RoleId, vip, Vip),
    {ok, Player};
%% 角色至尊VIP变化
handle_event(Player, #event_callback{type_id = ?EVENT_SUP_VIP_CHANGE}) ->
    #player_status{id = RoleId, figure = #figure{sup_vip = SupVip}} = Player,
    beauty_contest:update_role_info(RoleId, sup_vip, SupVip),
    {ok, Player};
%% 转职
handle_event(Player, #event_callback{type_id = ?EVENT_TURN_UP}) ->
    #player_status{id = RoleId, figure = #figure{turn = Turn}} = Player,
    beauty_contest:update_role_info(RoleId, turn, Turn),
    {ok, Player};
handle_event(Player, _) ->
    {ok, Player}.

%%%-------------------------------------------------------------------
%%% @doc
%%%     参赛数据处理
%%% @end
%%%-------------------------------------------------------------------
%% @doc 获得玩家当前参赛数据
statistics_contest_data(RoleId) when is_integer(RoleId) ->
    Figure = lib_role:get_role_figure(RoleId),
    statistics_contest_data(Figure);
statistics_contest_data(Figure) ->
    #figure{
        wear_fashion = Fashion,
        foster_skin = FosterSkin,
        role_foster = RoleFoster
    } = Figure,
    [
        get_fashion_model(?BC_DATA_CLOTH, Fashion, ?CLOTH),
        get_fashion_model(?BC_DATA_HEAD,  Fashion, ?HEAD_WEAR),
        get_foster_skin_with_fashion(?BC_DATA_WEAPON, FosterSkin, RoleFoster, Fashion, ?FWEAPON, ?WEAPON),
        get_foster_skin(?BC_DATA_HORSE,  FosterSkin, RoleFoster, ?FHORSE),
        get_foster_skin_with_fashion(?BC_DATA_WING,   FosterSkin, RoleFoster, Fashion, ?FWING, ?BACK_DECOR),
        get_foster_skin(?BC_DATA_PEARL,  FosterSkin, RoleFoster, ?FPEARL),
        get_fashion_model(?BC_DATA_HAIR, Fashion, ?HAIR)
    ].

%% 时装外观
get_fashion_model(Type, Fashion, Pos) ->
    case lists:keyfind(Pos, 1, Fashion) of
        {_, FashionId, Color} ->
            {Type, 0, FashionId, Color};
        _ ->
            {Type, 0, 0, 0}
    end.

%% 有时装的进阶外观
get_foster_skin_with_fashion(Type, FosterSkin, RoleFoster, Fashion, FosterPos, FashionPos) ->
    case lists:keyfind(FashionPos, 1, Fashion) of
        {_, FashionId, Color} ->
            {Type, ?BC_FOSTER_FASHION, FashionId, Color};
        _ ->
            get_foster_skin(Type, FosterSkin, RoleFoster, FosterPos)
    end.

%% 没有时装的进阶外观
get_foster_skin(Type, FosterSkin, RoleFoster, FosterPos) ->
    case lists:keyfind(FosterPos, 1, FosterSkin) of
        {_, {SkinId, Star}} when SkinId > 0 ->
            {Type, ?BC_FOSTER_SKIN, SkinId, Star};
        _ ->
            case lists:keyfind(FosterPos, 1, RoleFoster) of
                {_, Display} ->
                    {Type, ?BC_FOSTER_STAGE, Display, 0};
                _ ->
                    {Type, ?BC_FOSTER_STAGE, 0, 0}
            end
    end.

%% @doc 检查外观是否合法
check_contest_data(Player, CData) ->
    check_contest_data_do(Player, CData).
check_contest_data_do(Player, [{Type, Value1, Value2, Value3}|T]) ->
    Res =
    case Type of
        ?BC_DATA_CLOTH ->
            check_contest_data_fashion(Player, ?CLOTH, Value2, Value3);
        ?BC_DATA_HEAD ->
            check_contest_data_fashion(Player, ?HEAD_WEAR, Value2, Value3);
        ?BC_DATA_WEAPON ->
            check_contest_data_foster(Player, ?FWEAPON, Value1, Value2, Value3);
        ?BC_DATA_HORSE ->
            check_contest_data_foster(Player, ?FHORSE, Value1, Value2, Value3);
        ?BC_DATA_WING ->
            check_contest_data_foster(Player, ?FWING, Value1, Value2, Value3);
        ?BC_DATA_PEARL ->
            check_contest_data_foster(Player, ?FPEARL, Value1, Value2, Value3);
        ?BC_DATA_HAIR ->
            check_contest_data_fashion(Player, ?HAIR, Value2, Value3);
        _ ->
            {false, 0}
    end,
    case Res of
        true  -> check_contest_data_do(Player, T);
        Res -> Res
    end;
check_contest_data_do(_, []) -> true.

%% 检查时装外观是否合法
check_contest_data_fashion(_Player, _Pos, 0, 0) -> true;
check_contest_data_fashion(Player, Pos, FashionId, Color) ->
    #player_status{role_fashion = RoleFashion} = Player,
    #role_fashion{all_fashions = AllFashions} = RoleFashion,
    case lists:keyfind(Pos, #fashion_pos.pos_id, AllFashions) of
        #fashion_pos{fashion_list = List} ->
            case lists:keyfind(FashionId, #fashion_info.fashion_id, List) of
                #fashion_info{color_list = ColorList} ->
                    case lists:keymember(Color, 1, ColorList) of
                        true  -> true;
                        false -> {false, 8}
                    end;
                _ ->
                    {false, 2}
            end;
        _ ->
            {false, 3}
    end.

%% 检查进阶外观是否合法
%% 珍宝皮肤
check_contest_data_foster(_Player, _Pos, ?BC_FOSTER_SKIN, 0, _) -> true;
check_contest_data_foster(Player, Pos, ?BC_FOSTER_SKIN, SkinId, Star) ->
    #player_status{role_foster_skin = RoleSkin} = Player,
    #role_foster_skin{fosters = Fosters} = RoleSkin,
    case lists:keyfind(Pos,#cell_foster_skin.type,Fosters) of
        #cell_foster_skin{skins = Skins} ->
            case lists:keyfind(SkinId, #cell_skin.id, Skins) of
                #cell_skin{star = MaxStar} ->
                    case Star =< MaxStar of
                        true  -> true;
                        false -> {false, 10}
                    end;
                _ ->
                    {false, 4}
            end;
        _->
            {false, 5}
    end;
%% 进阶外观
check_contest_data_foster(_Player, _Pos, ?BC_FOSTER_STAGE, 0, _) -> true;
check_contest_data_foster(Player, Pos, ?BC_FOSTER_STAGE, Value2, _) ->
    #player_status{role_foster = RoleFoster} = Player,
    #role_foster{fosters=Fosters} = RoleFoster,
    case lists:keyfind(Pos,#cell_foster.type,Fosters) of
        #cell_foster{grade = Grade} ->
            case Grade >= Value2 of
                true  -> true;
                false -> {false, 9}
            end;
        _->
            {false, 6}
    end;
%% 时装
check_contest_data_foster(_Player, _Pos, ?BC_FOSTER_FASHION, 0, _) -> true;
check_contest_data_foster(Player, Pos, ?BC_FOSTER_FASHION, Value2, Value3) ->
    FashionPos =
    case Pos of
        ?FWEAPON -> ?WEAPON;
        ?FWING -> ?BACK_DECOR
    end,
    check_contest_data_fashion(Player, FashionPos, Value2, Value3);
check_contest_data_foster(_, _, _, _, _) -> {false, 7}.

%%%-------------------------------------------------------------------
%%% @doc
%%%     打包投票候选
%%% @end
%%%-------------------------------------------------------------------
pack_vote_candidate(Candidate) ->
    Members =
        [
            {RoleId, Name, ServerNum, Sex, Career, Turn, Vip, SupVip, CData}
            || #beauty_contest_role{
                role_id         = RoleId
                , server_num    = ServerNum
                , contest_data  = CData
                , picture       = #rec_picture{
                    name          = Name
                    , sex           = Sex
                    , career        = Career
                    , turn          = Turn
                    , vip           = Vip
                    , sup_vip       = SupVip
                }
            } <- Candidate
        ],
    {ok, Bin} = pt_416:write(41606, [Members]),
    Bin.

%%%-------------------------------------------------------------------
%%% @doc
%%%     投票成功
%%% @end
%%%-------------------------------------------------------------------
after_vote(Node, RoleId, Message) ->
    lib_player:apply_cast(Node, RoleId, ?APPLY_CAST_STATUS, ?NOT_HAND_OFFLINE, ?MODULE, vote_success, [Message]).
vote_success(Player, {VoteRole, VoteName, IsExtraAward, Add, VoteInfo, ZoneStage, Round, NowVotes}) ->
    #player_status{
        id = RoleId,
        figure = #figure{name = Name}
    } = Player,
    Now = utime:unixtime(),
    Award = case IsExtraAward of
                1  -> ?BC_VOTE_EXTRA_AWARD;
                0 -> ?BC_VOTE_NORMAL_AWARD
            end,
    %% 决赛的时候一次性给5份奖
    Player2 = lib_goods_api:send_reward(Player, lib_goods_util:goods_object_multiply_by(Award, Add), bc_vote),
    DailyVote = lib_daily:get_count(Player#player_status.id, ?MOD_BC, ?BC_COUNTER_DAILY_VOTE),
    VoteLimit = ?BC_VOTE_COUNTS(Round),
    IsExtraAward == 1 andalso contract_task_api:beauty_vote_trigger(RoleId, 1),
    lib_log_api:log_beauty_contest_vote(
        [czone_api:env_get_zone_id(), ZoneStage, RoleId, Name, Round, VoteInfo, VoteRole,
        VoteName, NowVotes, VoteLimit - DailyVote, IsExtraAward, util:term_to_bitstring(Award), Now]
    ),
    Player2.

%%%-------------------------------------------------------------------
%%% @doc
%%%     结算发奖
%%% @end
%%%-------------------------------------------------------------------
settlement([], _ClsType) -> ok;
settlement(Members, ?NODE_CENTER) ->
    [
        begin
            case Rank =:= 1 of
                true  ->
                    beauty_contest:notice_champion_in_server(
                        One#beauty_contest_role.zone_id, One#beauty_contest_role.server_num, One#beauty_contest_role.picture#rec_picture.name
                    );
                false ->
                    ignore
            end,
            clusters_center:apply_cast(ServerId, ?MODULE, send_settlement_mail, [RoleId, Rank])
        end
        ||#beauty_contest_role{server_id = ServerId, role_id = RoleId, rank = Rank} = One <- Members
    ];
settlement(Members, ?NODE_GAME) ->
    [
        begin
            case Rank =:= 1 of
                true  ->
                    Name = lib_role:get_role_name(RoleId),
                    beauty_contest_local:broad_cast_local_champion([Name]);
                false ->
                    ignore
            end,
            send_settlement_mail(RoleId, Rank)
        end
        ||#beauty_contest_role{role_id = RoleId, rank = Rank} <- Members
    ].

%% 冠亚军的x军
%% 16强内的显示x强
%% 16名外的显示排名
%% 冠军奖励
send_settlement_mail(RoleId, 1) ->
    Award = data_beauty_contest:get_rank_award(1),
    Title = utext:get(4160011),
    Content = utext:get(4160012),
    lib_mail_api:send_sys_mail([RoleId], Title, Content, Award),
    ok;
%% 亚军奖励
send_settlement_mail(RoleId, 2) ->
    Award = data_beauty_contest:get_rank_award(2),
    Title = utext:get(4160013),
    Content = utext:get(4160014),
    lib_mail_api:send_sys_mail([RoleId], Title, Content, Award),
    ok;
%% 16强奖励
send_settlement_mail(RoleId, Rank)
    when Rank =< 16 ->
    Grade =
        if
            Rank =< 4 -> 4;
            Rank =< 8 -> 8;
            true -> 16
        end,
    Award = data_beauty_contest:get_rank_award(Rank),
    Title = utext:get(4160009),
    Content = utext:get(4160010, [Grade]),
    lib_mail_api:send_sys_mail([RoleId], Title, Content, Award),
    ok;
%% 其他名次奖励
send_settlement_mail(RoleId, Rank) ->
    Award = data_beauty_contest:get_rank_award(Rank),
    Title = utext:get(4160001),
    Content = utext:get(4160002, [Rank]),
    lib_mail_api:send_sys_mail([RoleId], Title, Content, Award),
    ok.

%%%-------------------------------------------------------------------
%%% @doc
%%%     通知玩家活动结束
%%% @end
%%%-------------------------------------------------------------------
act_end_notice_role() ->
    lib_player:apply_cast_online(?MODULE, role_logic_act_end, []).

role_logic_act_end(Player) ->
    Player#player_status{beauty_contest = #role_beauty_contest{}}.