%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     福利卡：周卡/月卡/季卡 等等
%%% @end
%%%-------------------------------------------------------------------
-module(lib_recharge_welfare).
-author("liushl").

-include("server.hrl").
-include("rec_recharge.hrl").
-include("def_recharge.hrl").
-include("common.hrl").
-include("def_cache.hrl").
-include("def_event.hrl").
-include("rec_event.hrl").
-include("predefine.hrl").
-include("language.hrl").
-include("def_goods.hrl").
-include("def_module.hrl").
-include("recharge_act.hrl").
-include("def_fun.hrl").
-include("errcode.hrl").
-include("chat.hrl").
-include("goods.hrl").
-include("figure.hrl").
-include("custom_act.hrl").
-include("drop.hrl").
-include("team.hrl").
%% API
-export([]).
-compile (export_all).

login(Player) ->
    #player_status{id = RoleId} = Player,
    %% 福利卡初始化
    ProductList = db_get_recharge(RoleId),
    #player_status{recharge_act_status = RechargeActStatus} = Player,
    Now = utime:unixtime(),
    F = fun([ProductId, Time, _LeftCount, BuyTime, EndTime], LastList) ->
        LeftCount = utime:day_span(Now, EndTime),
        [#recharge_goods{product_id = ProductId, time = Time, left_count = LeftCount, buy_time = BuyTime, end_time = EndTime} | LastList]
        end,
    LastList = lists:foldl(F, [], ProductList),
    case is_record(RechargeActStatus, recharge_act_status) of
        true ->
            NewRechargeActStatus = RechargeActStatus#recharge_act_status{welfare = LastList};
        _ ->
            NewRechargeActStatus = #recharge_act_status{welfare = LastList}
    end,
    Player#player_status{recharge_act_status = NewRechargeActStatus}.

%% 计算剩余领取天数
calc_left_count(Days, BuyTime) ->
    if
        Days > 0 ->
            DiffDay = utime:diff_day(BuyTime),
            min(Days, max(0, Days - DiffDay));
        true -> 0
    end.

%% 购买福利卡
deal_with_charge(PS, ProductCfg, _PayNo) ->
    #player_status{id = RoleId, figure = Figure, recharge_act_status = RechargeActStatus, team = Team} = PS,
    #figure{name = Name, lv = Lv, vip = Vip} = Figure,
    #recharge_act_status{welfare = Welfare} = RechargeActStatus,
    #base_recharge_product{
        product_id = ProductId,
        product_name = ProductName,
        product_type = Type,
        product_subtype = SubType
    } = ProductCfg,
    #recharge_welfare{days = Days, buy_reward = BuyReward} = data_recharge_act:get_welfare(ProductId),
    Now = utime:unixtime(),
    case lists:keyfind(ProductId, #recharge_goods.product_id, Welfare) of
        #recharge_goods{end_time = EndTime} when EndTime > Now -> %% 未过期续费
            NewEndTime = utime:that_day_after(EndTime, Days - 1),
            Time = 0;
        _ ->
            NewEndTime = utime:that_day_after(Days) - 1,
            Time  = 0
    end,
    case lib_recharge_check:check_product(ProductId) of
        {true, _} ->
            NewCount = utime:day_span(Now, NewEndTime) - 1,
            db_replace_recharge(RoleId, ProductId, Time, NewCount, Now, NewEndTime),
            RechargeGoods = #recharge_goods{product_id = ProductId, left_count = NewCount, time = Time, buy_time = Now, end_time = NewEndTime},
            % 找出已购买过的同类型的尊享卡的product_id
            ProductIds = [Id || #recharge_goods{product_id = Id} <- Welfare, Id =/= ProductId],
            ExistId = lists:foldl(fun(Id, Exist) ->
                case data_recharge:get_product(Id) of
                    #base_recharge_product{product_type = Type, product_subtype = SubType} ->
                        db_delete_recharge(RoleId, Id),
                        Id;
                    _ -> Exist
                end end, 0, ProductIds),
            % 移除已购买过的同类型尊享卡
            WelfareDelete = lists:keydelete(ExistId, #recharge_goods.product_id, Welfare),
            NewWelfare = lists:keystore(ProductId, #recharge_goods.product_id, WelfareDelete, RechargeGoods),
            NewRechargeActStatus = RechargeActStatus#recharge_act_status{welfare = NewWelfare},
            NewPs = PS#player_status{recharge_act_status = NewRechargeActStatus},
            % 记录日志
            RechargeTotal = lib_recharge_data:get_total_rmb(RoleId),
            lib_log_api:log_charge_goods([RoleId, ProductId, Type, SubType, ProductName, RechargeTotal, Lv, Vip, Now]),
            get_welfare(NewPs),
            custom_act_mobilize:update_mobilize_task(RoleId, supremecard, 1),
            %% 传闻
            if
                SubType == ?WELFARE_SUBTYPE_WEEK ->
                    lib_chat:send_TV({all}, ?MOD_RECHARGE_ACT, 4, [Name]);
                SubType == ?WELFARE_SUBTYPE_MONTH ->
                    lib_chat:send_TV({all}, ?MOD_RECHARGE_ACT, 5, [Name]);
                true ->
                    lib_chat:send_TV({all}, ?MOD_RECHARGE_ACT, 6, [Name])
            end,
            %% 更新队伍数据
            #status_team{team_id = TeamId} = Team,
            if
                TeamId>0 ->
                    Data = get_welfare_data(NewPs),
                    mod_team:cast_to_team(TeamId, {'update_team_mb', RoleId, [{welfare, Data}]});
                true ->
                    skip
            end,
            case BuyReward of
                [] ->
                    NewPs;
                _ ->
                    Title = ?LAN_MSG(?LAN_TITLE_RECHAEGE_REWARD),
                    Content = ?LAN_MSG(?LAN_TITLE_RECHAEGE_REWARD),
                    Produce = #produce{title = Title, content = Content, type = welfare_card, reward = BuyReward, remark = io_lib:format("SubType:~p,ProductId:~p", [SubType, ProductId])},
                    {ok, NewPlayer} = lib_goods_api:send_reward_with_mail(NewPs, Produce, ?MOD_RECHARGE_ACT),
                    {ok, NewPlayer}
            end;
        {false, Res} ->
            ?ERR("check fail welfare Type:~p, SubType:~p, ProductId:~p _R:~p ~n", [?PRODUCT_TYPE_WELFARE, SubType, ProductId, Res]),
            Res
    end.

%% 查看福利卡
get_welfare(Player) ->
    #player_status{id = RoleId, sid = Sid, recharge_act_status = RechargeActStatus} = Player,
    #recharge_act_status{welfare = Welfare} = RechargeActStatus,
    CfgList = data_recharge_act:get_welfare_product(),
    AllActState = lists:foldl(fun(#recharge_goods{product_id = Id, end_time = EndTime}, ActState) ->
        NowTime = utime:unixtime(),
        if
            NowTime >= EndTime ->  %% 过期
                ActState;
            true ->     %% 未过期
                #base_recharge_product{product_type = Type, product_subtype = SubType} = data_recharge:get_product(Id),
                [{{Type, SubType}, Id} | ActState]
        end
                              end, [], Welfare),
    Info = [begin
                case data_recharge:get_product(ProductId) of
                    #base_recharge_product{product_type = Type, product_subtype = SubType} ->
                        {State, RemainingTimes} = check_state(ProductId, Welfare),
                        {Type, SubType, ProductId, State, RemainingTimes};
                    _ ->
                        ?ERR("config err product_id = ~p", [ProductId]),
                        {}
                end
            end || ProductId <- CfgList],
    F = fun({Type, SubType, ProductId, State, _RemainingTimes} = Item, {Expired, AvailableList}) ->
            Result = check_product(ProductId),
            case State > 0 orelse Result == true andalso check_all_buy_type(ProductId, AllActState) of
                true when State == 3 ->
                    if
                        Result == true -> {Expired, [{Type, SubType, ProductId, 2, 0} | AvailableList]};
                        true -> {[{Type, SubType} | Expired], AvailableList}
                    end;
                true -> {Expired, [Item | AvailableList]};
                _ -> {Expired, AvailableList}
            end;
        (_, {Expired, AvailableList}) ->
            {Expired, AvailableList}
        end,
    {ExpiredList, List} = lists:foldl(F, {[], []}, Info),
    ShowList = lists:foldl(fun({Type, SubType, ProductId, State, RemainingTimes}, AvailableList) ->
        case lists:keyfind(ProductId, #recharge_goods.product_id, Welfare) of
            #recharge_goods{end_time = EndTime} -> skip;
            _ -> EndTime = 0
        end,
        LeftTimes =
        if
            SubType == ?WELFARE_SUBTYPE_WEEK ->
                Value = lib_daily:get_count(RoleId, ?MOD_RECHARGE_ACT, 101, 1),
                max(?WEEK_MAX - Value, 0);
            SubType == ?WELFARE_SUBTYPE_MONTH ->
                Value = lib_daily:get_count(RoleId, ?MOD_RECHARGE_ACT, 102, 1),
                max(?MONTH_MAX - Value, 0);
            true ->
                Value = lib_daily:get_count(RoleId, ?MOD_RECHARGE_ACT, 103, 1),
                max(?QUARTER_MAX - Value, 0)
        end,
        case lists:member({Type, SubType}, ExpiredList) of
            true -> [{Type, SubType, ProductId, 2, 0, EndTime, LeftTimes} | AvailableList];
            _ -> [{Type, SubType, ProductId, State, RemainingTimes, EndTime, LeftTimes} | AvailableList]
        end
                           end, [], List),
    lib_server_send:send_to_sid(Sid, pt_159, 15901, [ShowList]).

%%检查购买状态
check_state(ProductId, Welfare) ->
    Today = utime:unixdate(),
    case lists:keyfind(ProductId, #recharge_goods.product_id, Welfare) of
        #recharge_goods{product_id = ProductId, time = GotTime, end_time = EndTime} ->
            NowTime = utime:unixtime(),
            if
                NowTime >= EndTime ->  %% 已过期
                    {3, 0};
                GotTime >= Today -> %% 已领取
                    {2, utime:day_span(Today, EndTime)};
                true ->  %%可领取
                    {1, utime:day_span(Today, EndTime)}
            end;
        _ ->
            {0, 0}
    end.

%%检查是否购买过同类型尊享卡且未结束&是否超过每日购买次数
check_same_type(Player, ProductId) ->
    #player_status{id = RoleId, recharge_act_status = RechargeActStatus} = Player,
    #recharge_act_status{welfare = Welfare} = RechargeActStatus,
    #base_recharge_product{product_type = Type, product_subtype = SubType} = data_recharge:get_product(ProductId),
    ProductIds = data_recharge:get_product_ids_by_type(Type, SubType),
    F = fun(Id, Result) ->
        {State, _RemainingTimes} = lib_recharge_welfare:check_state(Id, Welfare),
        case State =:= 0 orelse State =:= 3 of
            true -> Result;
            _ -> Result + 1
        end
        end,
    AlreadyHas = lists:foldl(F, 0, ProductIds),
    if
        SubType == ?WELFARE_SUBTYPE_WEEK ->
            Value = lib_daily:get_count(RoleId, ?MOD_RECHARGE_ACT, 101, 1),
            lib_daily:set_count(RoleId, ?MOD_RECHARGE_ACT, 101, 1, Value + 1),
            ?IF(Value > ?WEEK_MAX, 2, AlreadyHas);
        SubType == ?WELFARE_SUBTYPE_MONTH ->
            Value = lib_daily:get_count(RoleId, ?MOD_RECHARGE_ACT, 102, 1),
            lib_daily:set_count(RoleId, ?MOD_RECHARGE_ACT, 102, 1, Value + 1),
            ?IF(Value > ?MONTH_MAX, 2, AlreadyHas);
        true ->
            Value = lib_daily:get_count(RoleId, ?MOD_RECHARGE_ACT, 103, 1),
            lib_daily:set_count(RoleId, ?MOD_RECHARGE_ACT, 103, 1, Value + 1),
            ?IF(Value > ?QUARTER_MAX, 2, AlreadyHas)
    end.

%% 此类型是否购买过且未过期
check_all_buy_type(ProductId, AllActState) ->
    #base_recharge_product{product_type = Type, product_subtype = SubType} = data_recharge:get_product(ProductId),
    case lists:keyfind({Type, SubType}, 1, AllActState) of
        {{Type, SubType}, ProductId} -> true;
        {{Type, SubType}, _ProductId} -> false;
        _ -> true
    end.


check_product(ProductId) ->
    case lib_recharge_check:check_product(ProductId) of
        {true, _} ->
            true;
        _ ->
            false
    end.

%% 领取福利卡福利
get_welfare_reward(Player, ProductId) ->
    #player_status{id = RoleId} = Player,
    Checkist = [product, buy, already, bag, send],
    case check(Player, ProductId, Checkist) of
        {true, NewPlayer} ->
            get_welfare(NewPlayer),
            lib_activitycalen_api:role_success_end_activity(RoleId, ?MOD_RECHARGE_ACT, ?MOD_RECHARGE_ACT_GET_WEAFARE_REWARD),
            ErrCode = ?SUCCESS;
        {false, ErrCode, NewPlayer} ->
            skip
    end,
    lib_server_send:send_to_uid(RoleId, pt_159, 15902, [ErrCode]),
    NewPlayer.

%% 购买月卡强化装备成功率增加5%
equip_strength_add(Player) ->
    case is_buy_welfare(Player, ?WELFARE_SUBTYPE_MONTH) of
        true -> 5;
        false -> 0
    end.

%% 购买周卡进化装备成功率增加5%
equip_rise_star_add(Player) ->
    case is_buy_welfare(Player, ?WELFARE_SUBTYPE_WEEK) of
        true -> 5;
        false -> 0
    end.

%% 购买月卡、季卡增加幻魔橙装爆率
get_welfare_radio(Player, MonArgs) ->
    #mon_args{boss = Boss} = MonArgs,
    case lists:member(Boss, ?BOSS_TYPE_LIST) of
        true ->
            MonthCard = is_buy_welfare(Player, ?WELFARE_SUBTYPE_MONTH),
            QuarterCard = is_buy_welfare(Player, ?WELFARE_SUBTYPE_QUARTER),
            if
                MonthCard andalso QuarterCard ->
                    %% 同时买了月卡、季卡增加6%橙装爆率
                    ?WELFARE_MONTH_AND_QUARTER_ADD;
                MonthCard ->
                    %% 买了月卡增加2%橙装爆率
                    ?WELFARE_MONTH_ADD;
                QuarterCard ->
                    %% 买了季卡增加4%橙装爆率
                    ?WELFARE_QUARTER_ADD;
                true ->
                    0
            end;
        false ->
            0
    end.

%% 是否购买过尊享卡且在有效期内
is_buy_welfare(Player, Type) ->
    #player_status{recharge_act_status = RechargeActStatus} = Player,
    #recharge_act_status{welfare = WelfareList} = RechargeActStatus,
    F = fun(#recharge_goods{product_id = ProductId, end_time = EndTime}) ->
        case data_recharge:get_product(ProductId) of
            #base_recharge_product{product_subtype = Type}  ->
                NowTime = utime:unixtime(),
                ?IF(EndTime >= NowTime, true, false);
            _ ->
                false
        end
    end,
    lists:any(F, WelfareList).

%% 获取尊享卡数据
get_welfare_data(Player) ->
    #player_status{recharge_act_status = RechargeActStatus} = Player,
    #recharge_act_status{welfare = WelfareList} = RechargeActStatus,
    F = fun(#recharge_goods{product_id = ProductId, end_time = EndTime}, Data) ->
        case data_recharge:get_product(ProductId) of
            #base_recharge_product{product_subtype = Type}  ->
                NowTime = utime:unixtime(),
                if
                    EndTime >= NowTime ->
                        [{Type, EndTime}|Data];
                    true ->
                        Data
                end;
            _ ->
                Data
        end
        end,
    lists:foldl(F, [], WelfareList).

%%------------------------check----------------------------------------
check(Player, _Args, []) -> {true, Player};
check(Player, Args, [H | T]) ->
    case do_check(Player, Args, H) of
        {true, NewPlayer} ->
            check(NewPlayer, Args, T);
        {false, ErrCode, NewPlayer} ->
            {false, ErrCode, NewPlayer}
    end.
%% check 福利卡是否存在配置
do_check(Player, ProductId, product) ->
    IdList = data_recharge_act:get_welfare_product(),
    case lists:member(ProductId, IdList) of
        true ->
            {true, Player};
        false ->
            {false, ?ERRCODE(err159_1_not_welfare), Player}
    end;

do_check(Player, ProductId, buy) ->
    #player_status{recharge_act_status = RechargeActStatus} = Player,
    #recharge_act_status{welfare = Welfare} = RechargeActStatus,
    case lists:keyfind(ProductId, #recharge_goods.product_id, Welfare) of
        #recharge_goods{product_id = ProductId, end_time = EndTime} ->
            case data_recharge_act:get_welfare(ProductId) of
                #recharge_welfare{} ->
                    Now = utime:unixtime(),
                    if
                        EndTime > Now -> {true, Player};
                        true -> {false, ?ERRCODE(err159_3_not_buy)}
                    end;
                _ -> {false, ?MISSING_CONFIG, Player}
            end;
        _ -> {false, ?ERRCODE(err159_3_not_buy), Player}
    end;

%% check 福利卡是否已领取过
do_check(Player, ProductId, already) ->
    #player_status{recharge_act_status = RechargeActStatus} = Player,
    #recharge_act_status{welfare = Welfare} = RechargeActStatus,
    Today = utime:unixdate(),
    case lists:keyfind(ProductId, #recharge_goods.product_id, Welfare) of
        #recharge_goods{time = GotTime} when GotTime < Today ->
            {true, Player};
        _ ->
            {false, ?ERRCODE(err159_4_already_get), Player}
    end;
%% check 背包
do_check(Player, ProductId, bag) ->
    #recharge_welfare{reward = Reward} = data_recharge_act:get_welfare(ProductId),
    case lib_goods_api:can_give_goods(Player, Reward) of
        true ->
            {true, Player};
        _ ->
            {false, ?ERRCODE(err159_5_bag_not_enough), Player}
    end;

do_check(Player, ProductId, send) ->
    #player_status{id = RoleId, recharge_act_status = RechargeActStatus} = Player,
    #recharge_act_status{welfare = Welfare} = RechargeActStatus,
    #recharge_goods{buy_time = BuyTime, end_time = EndTime} = RechargeGoods = lists:keyfind(ProductId, #recharge_goods.product_id, Welfare),
    #recharge_welfare{days = Days} = data_recharge_act:get_welfare(ProductId),
    Now = utime:unixtime(),
    NewCount = utime:day_span(Now, EndTime) - 1,
    NewRechargeGoods = RechargeGoods#recharge_goods{time = Now},
    NewWelfare = lists:keystore(ProductId, #recharge_goods.product_id, Welfare, NewRechargeGoods),
    TmpPlayer = Player#player_status{recharge_act_status = RechargeActStatus#recharge_act_status{welfare = NewWelfare}},
    #recharge_welfare{reward = Reward, double_week = DoubleWeek} = data_recharge_act:get_welfare(ProductId),
    Week = utime:day_of_week(),
    case is_list(DoubleWeek) andalso lists:member(Week, DoubleWeek) of
        true ->
            Value = 2;
        _ ->
            Value = 1
    end,
    RewardList = [{T, TI, N * Value} || {T, TI, N} <- Reward],
    NewPlayer = lib_goods_api:send_reward(TmpPlayer, RewardList, recharge_welfare),
    db_replace_recharge(RoleId, ProductId, Now, NewCount, BuyTime, EndTime),
    % 记录日志
    lib_log_api:log_recharge_welfare([RoleId, ProductId, Days, NewCount, util:term_to_string(RewardList), Now]),
    {true, NewPlayer};

do_check(Player, _Args, _R) ->
    {false, ?FAIL, Player}.

%% ---------------------sql--------------------------------
db_get_recharge(RoleId) ->
    Sql = io_lib:format(<<"select `product_id`, `time`, `left_count`, `buy_time`, `end_time` from `recharge_act` where role_id = ~p">>, [RoleId]),
    db:get_all(Sql).

db_replace_recharge(RoleId, ProductId, GotTime, LeftCount, BuyTime, EndTime) ->
    Sql = io_lib:format(<<"replace into  `recharge_act` (`role_id`, `product_id`, `time`, `left_count`, `buy_time`, `end_time`) values(~p, ~p, ~p, ~p, ~p, ~p)">>, [RoleId, ProductId, GotTime, LeftCount, BuyTime, EndTime]),
    db:execute(Sql).

db_delete_recharge(RoleId, ProductId) ->
    Sql = io_lib:format(<<"delete  from `recharge_act` where role_id = ~p and product_id = ~p">>, [RoleId, ProductId]),
    db:execute(Sql).