%%%--------------------------------------
%%% @Module  : mod_lucky_wheel
%%% @Author  : huyihao
%%% @Created : 2018.08.06
%%% @Description:  幸运转盘
%%%--------------------------------------
-module(mod_lucky_wheel).

-include("errcode.hrl").
-include("common.hrl").
-include("def_module.hrl").
-include("custom_act.hrl").
-include("lucky_wheel.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([
    open_lucky_wheel/2,
    get_not_roll_id_list/2,
    add_limit_times/1
    ]).

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

open_lucky_wheel(SubType, RoleId) ->
    gen_server:cast(?MODULE, {open_lucky_wheel, SubType, RoleId}).

add_limit_times(Args) ->
    gen_server:cast(?MODULE, {add_limit_times, Args}).

get_not_roll_id_list(SubType, RoleId) ->
    gen_server:call(?MODULE, {get_not_roll_id_list, SubType, RoleId}).

init([]) ->
    F1 = fun(AllLimitSqlInfo, SubTypeList11) ->
        [SubType, RollId, Times] = AllLimitSqlInfo,
        case lists:keyfind(SubType, #lucky_wheel_info.sub_type, SubTypeList11) of
            false ->
                NewLuckyWheelInfo = #lucky_wheel_info{
                    sub_type = SubType,
                    times_list = [{RollId, Times}]
                };
            LuckyWheelInfo ->
                #lucky_wheel_info{
                    times_list = OldTimesList
                } = LuckyWheelInfo,
                NewLuckyWheelInfo = LuckyWheelInfo#lucky_wheel_info{
                    times_list = [{RollId, Times}|OldTimesList]
                }
        end,
        lists:keystore(SubType, #lucky_wheel_info.sub_type, SubTypeList11, NewLuckyWheelInfo)
    end,
    AllLimitSqlList = db:get_all(?SelectLuckyWheelAllLimitAllSql),
    NewSubTypeList1 = lists:foldl(F1, [], AllLimitSqlList),
    F2 = fun(PlayerLimitSqlInfo, SubTypeList12) ->
        [SubType, RoleId, RollId, Times] = PlayerLimitSqlInfo,
        case lists:keyfind(SubType, #lucky_wheel_info.sub_type, SubTypeList12) of
            false ->
                NewLWPlayerInfo = #lucky_wheel_player_info{
                    role_id = RoleId,
                    pleyer_times_list = [{RollId, Times}]
                },
                NewLuckyWheelInfo = #lucky_wheel_info{
                    sub_type = SubType,
                    player_list = [NewLWPlayerInfo]
                };
            LuckyWheelInfo ->
                #lucky_wheel_info{
                    player_list = OldPlayerList
                } = LuckyWheelInfo,
                case lists:keyfind(RoleId, #lucky_wheel_player_info.role_id, OldPlayerList) of
                    false ->
                        NewLWPlayerInfo = #lucky_wheel_player_info{
                            role_id = RoleId,
                            pleyer_times_list = [{RollId, Times}]
                        };
                    LWPlayerInfo ->
                        #lucky_wheel_player_info{
                            pleyer_times_list = OldPlayerTimesList
                        } = LWPlayerInfo,
                        NewLWPlayerInfo = LWPlayerInfo#lucky_wheel_player_info{
                            pleyer_times_list = [{RollId, Times}|OldPlayerTimesList]
                        }
                end,
                NewLuckyWheelInfo = LuckyWheelInfo#lucky_wheel_info{
                    player_list = lists:keystore(RoleId, #lucky_wheel_player_info.role_id, OldPlayerList, NewLWPlayerInfo)
                }
        end,
        lists:keystore(SubType, #lucky_wheel_info.sub_type, SubTypeList12, NewLuckyWheelInfo)
    end,
    PlayerLimitSqlList = db:get_all(?SelectLuckyWheelPlayerLimitAllSql),
    NewSubTypeList = lists:foldl(F2, NewSubTypeList1, PlayerLimitSqlList),
    % NextTime = utime:unixdate() + 24*60*60 - utime:unixtime() + 10,
    NextTime = utime:tomorrow() - utime:unixtime() + 10,
    CheckTimer = erlang:send_after(NextTime*1000, self(), {luycky_wheel_check_end}),
    State = #lucky_wheel_state{
        sub_type_list = NewSubTypeList,
        check_timer = CheckTimer
    },
    {ok, State}.

handle_call(Request, From, State) ->
    case catch do_handle_call(Request, From, State) of
        {'EXIT', _Reason} ->
            ?ERR("~p ~p _Reason:~p~n", [?MODULE, ?LINE, _Reason]),
            {reply, ok, State};
        Result ->
            Result
    end.

do_handle_call({get_not_roll_id_list, SubType, RoleId}, _From, State) ->
    #lucky_wheel_state{
        sub_type_list = SubTypeList
    } = State,
    case lists:keyfind(SubType, #lucky_wheel_info.sub_type, SubTypeList) of
        false ->
            ReturnList = [];
        LuckyWheelInfo ->
            #lucky_wheel_info{
                times_list = TimesList,
                player_list = PlayerList
            } = LuckyWheelInfo,
            F = fun(RollId, ReturnList1) ->
                #lucky_wheel_reward_con{
                    single_limit = SingleLimit,
                    all_limit = AllLimit
                } = data_lucky_wheel:get_lucky_wheel_reward_con(RollId),
                case SingleLimit =:= 0 andalso AllLimit =:= 0 of
                    true ->
                        ReturnList1;
                    false ->
                        case AllLimit of
                            0 ->
                                ReturnList1A = ReturnList1;
                            _ ->
                                case lists:keyfind(RollId, 1, TimesList) of
                                    false ->
                                        ReturnList1A = ReturnList1;
                                    {_, AllTimes} ->
                                        case AllTimes >= AllLimit of
                                            false ->
                                                ReturnList1A = ReturnList1;
                                            true ->
                                                ReturnList1A = [RollId|ReturnList1]
                                        end
                                end
                        end,
                        case SingleLimit of
                            0 ->
                                ReturnList1B = ReturnList1A;
                            _ ->
                                case lists:keyfind(RoleId, #lucky_wheel_player_info.role_id, PlayerList) of
                                    false ->
                                        ReturnList1B = ReturnList1A;
                                    LWPlayerInfo ->
                                        #lucky_wheel_player_info{
                                            pleyer_times_list = PlayerTimesList
                                        } = LWPlayerInfo,
                                        case lists:keyfind(RollId, 1, PlayerTimesList) of
                                            false ->
                                                ReturnList1B = ReturnList1A;
                                            {_, PlayerTimes} ->
                                                case PlayerTimes >= SingleLimit of
                                                    false ->
                                                        ReturnList1B = ReturnList1A;
                                                    true ->
                                                        case lists:member(RollId, ReturnList1A) of
                                                            false ->
                                                                ReturnList1B = [RollId|ReturnList1A];
                                                            true ->
                                                                ReturnList1B = ReturnList1A
                                                        end
                                                end
                                        end
                                end
                        end,
                        ReturnList1B
                end
            end,
            RollIdList = data_lucky_wheel:get_lw_roll_id_list(),
            ReturnList = lists:foldl(F, [], RollIdList)
    end,
    {reply, ReturnList, State};

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

handle_cast(Info, State) ->
    case catch do_handle_cast(Info, State) of
        {'EXIT', _Reason} ->
            ?ERR("~p ~p _Reason:~p~n", [?MODULE, ?LINE, _Reason]),
            {noreply, State};
        Res ->
            Res
    end.

do_handle_cast({open_lucky_wheel, SubType, RoleId}, State) ->
    #lucky_wheel_state{
        sub_type_list = SubTypeList
    } = State,
    case lists:keyfind(SubType, #lucky_wheel_info.sub_type, SubTypeList) of
        false ->
            LogList = [];
        SubTypeInfo ->
            #lucky_wheel_info{
                log_list = LogList
            } = SubTypeInfo
    end,
    {ok, Bin} = pt_331:write(33165, [?SUCCESS, SubType, LogList]),
    lib_server_send:send_to_uid(RoleId, Bin),
    {noreply, State};

do_handle_cast({add_limit_times, Args}, State) ->
    #lucky_wheel_state{
        sub_type_list = SubTypeList
    } = State,
    [SubType, RoleId, Name, RollId, SingleLimit, AllLimit] = Args,
    case lists:keyfind(SubType, #lucky_wheel_info.sub_type, SubTypeList) of
        false ->
            case AllLimit of
                0 ->
                    NewTimesList = [];
                _ ->
                    NewTimesList = [{RollId, 1}],
                    ReSql1 = io_lib:format(?ReplaceLuckyWheelAllLimitSql, [SubType, RollId, 1]),
                    db:execute(ReSql1)
            end,
            case SingleLimit of
                0 ->
                    NewPlayerList = [];
                _ ->
                    NewLWPlayerInfo = #lucky_wheel_player_info{
                        role_id = RoleId,
                        pleyer_times_list = [{RollId, 1}]
                    },
                    NewPlayerList = [NewLWPlayerInfo],
                    ReSql2 = io_lib:format(?ReplaceLuckyWheelPlayerLimitSql, [SubType, RoleId, RollId, 1]),
                    db:execute(ReSql2)
            end,
            NewLogList = [{RoleId, Name, RollId}],
            NewLuckyWheelInfo = #lucky_wheel_info{
                sub_type = SubType,
                times_list = NewTimesList,
                player_list = NewPlayerList,
                log_list = NewLogList
            };
        LuckyWheelInfo ->
            #lucky_wheel_info{
                times_list = TimesList,
                player_list = PlayerList,
                log_list = LogList
            } = LuckyWheelInfo,
            case AllLimit of
                0 ->
                    NewTimesList = TimesList;
                _ ->
                    case lists:keyfind(RollId, 1, TimesList) of
                        false ->
                            NewAllTimes = 1,
                            NewTimesList = [{RollId, NewAllTimes}|TimesList];
                        {_, AllTimes} ->
                            NewAllTimes = AllTimes+1,
                            NewTimesList = lists:keyreplace(RollId, 1, TimesList, {RollId, NewAllTimes})
                    end,
                    ReSql1 = io_lib:format(?ReplaceLuckyWheelAllLimitSql, [SubType, RollId, NewAllTimes]),
                    db:execute(ReSql1)
            end,
            case SingleLimit of
                0 ->
                    NewPlayerList = PlayerList;
                _ ->
                    case lists:keyfind(RoleId, #lucky_wheel_player_info.role_id, PlayerList) of
                        false ->
                            NewPlayerTimes = 1,
                            NewLWPlayerInfo = #lucky_wheel_player_info{
                                role_id = RoleId,
                                pleyer_times_list = [{RollId, 1}]
                            };
                        LWPlayerInfo ->
                            #lucky_wheel_player_info{
                                pleyer_times_list = PlayerTimesList
                            } = LWPlayerInfo,
                            case lists:keyfind(RollId, 1, PlayerTimesList) of
                                false ->
                                    NewPlayerTimes = 1,
                                    NewPlayerTimesList = [{RollId, 1}|PlayerTimesList];
                                {_, PlayerTimes} ->
                                    NewPlayerTimes = PlayerTimes+1,
                                    NewPlayerTimesList = lists:keyreplace(RollId, 1, PlayerTimesList, {RollId, PlayerTimes+1})
                            end,
                            NewLWPlayerInfo = LWPlayerInfo#lucky_wheel_player_info{
                                pleyer_times_list = NewPlayerTimesList
                            }
                    end,
                    NewPlayerList = lists:keystore(RoleId, #lucky_wheel_player_info.role_id, PlayerList, NewLWPlayerInfo),
                    ReSql2 = io_lib:format(?ReplaceLuckyWheelPlayerLimitSql, [SubType, RoleId, RollId, NewPlayerTimes]),
                    db:execute(ReSql2)
            end,
            NewLogList = lists:sublist([{RoleId, Name, RollId}|LogList], ?LuckyWheelLogLen),
            NewLuckyWheelInfo = LuckyWheelInfo#lucky_wheel_info{
                times_list = NewTimesList,
                player_list = NewPlayerList,
                log_list = NewLogList
            }
    end,
    NewSubTypeList = lists:keystore(SubType, #lucky_wheel_info.sub_type, SubTypeList, NewLuckyWheelInfo),
    NewState = State#lucky_wheel_state{
        sub_type_list = NewSubTypeList
    },
    {noreply, NewState};

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

handle_info(Info, State) ->
    case catch do_handle_info(Info, State) of
        {'EXIT', _Reason} ->
            ?ERR("~p ~p _Reason:~p~n", [?MODULE, ?LINE, _Reason]),
            {noreply, State};
        Res ->
            Res
    end.

do_handle_info({luycky_wheel_check_end}, State) ->
    #lucky_wheel_state{
        sub_type_list = SubTypeList,
        check_timer = CheckTimer
    } = State,
    util:cancel_timer(CheckTimer),
    F = fun(SubTypeInfo, {DeleteSubTypeList1, NewSubTypeList1}) ->
        #lucky_wheel_info{
            sub_type = SubType
        } = SubTypeInfo,
        case lib_custom_act_api:is_open_act(50, SubType) of
            false ->
                {[SubType|DeleteSubTypeList1], NewSubTypeList1};
            true ->
                {DeleteSubTypeList1, [SubTypeInfo|NewSubTypeList1]}
        end
    end,
    {DeleteSubTypeList, NewSubTypeList} = lists:foldl(F, {[], []}, SubTypeList),
    case DeleteSubTypeList of
        [] ->
            skip;
        _ ->
            SDeleteSubTypeList = util:link_list(DeleteSubTypeList),
            ReSql1 = io_lib:format(?DelectLuckyWheelAllLimitSql, [SDeleteSubTypeList]),
            db:execute(ReSql1),
            ReSql2 = io_lib:format(?DelectLuckyWheelPlayerLimitSql, [SDeleteSubTypeList]),
            db:execute(ReSql2)
    end,
    NewCheckTimer = erlang:send_after(24*60*60*1000, self(), {luycky_wheel_check_end}),
    NewState = State#lucky_wheel_state{
        sub_type_list = NewSubTypeList,
        check_timer = NewCheckTimer
    },
    {noreply, NewState};

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

terminate(_Reason, _State) -> ok.

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