%% ---------------------------------------------------------------------------
%% @doc lib_mail_api

%% @author hjh
%% @since  2016-11-18
%% @deprecated  邮件
%% ---------------------------------------------------------------------------
-module(lib_mail_api).

-export([]).
-compile(export_all).

-include("mail.hrl").
-include("goods.hrl").
-include("def_module.hrl").
-include("common.hrl").

%% ---------------------------------------------------------------------------
%% @doc 发送系统邮件(PHP不能调用该函数)
-spec send_sys_mail(PlayerInfoList, Title, Content, CmAttachment) -> ok when
    PlayerInfoList      ::  list(), % 名字(string() | binary())列表、 角色Id列表
    Title               ::  list() | binary(),
    Content             ::  list() | binary(),
    CmAttachment        ::  list() | binary().  % {?TYPE_GOODS|?TYPE_GOOD|?TYPE_BGOLD|?TYPE_GCOIN, GoodsTypeId, Num}
%%-----------------------------------------------------------------------------
send_sys_mail(PlayerInfoList, Title, Content, CmAttachment) ->
    SendLogType = lib_mail:get_send_log_type(CmAttachment),
    lib_mail:send_sys_mail(PlayerInfoList, ?MOD_NONE, ?MOD_NONE, Title, Content, CmAttachment, SendLogType).

%% 普通使用邮件推荐使用这个 (PHP不能调用该函数)
send_sys_mail(PlayerInfoList, ModuleId, Title, Content, CmAttachmentStr) when is_integer(ModuleId) ->
    SendLogType = lib_mail:get_send_log_type(CmAttachmentStr),
    lib_mail:send_sys_mail(PlayerInfoList, ModuleId, ?MOD_NONE, Title, Content, CmAttachmentStr, SendLogType).

%% 定制活动建议走这个，多了一个模块子类型（PHP不能调用此函数）
send_sys_mail(PlayerInfoList, ?MOD_MARKET = ModuleId, SubModuleId, Title, Content, CmAttachmentStr) ->
    send_auction_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, CmAttachmentStr);
send_sys_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, CmAttachmentStr) when is_integer(ModuleId), is_integer(SubModuleId) ->
    SendLogType = lib_mail:get_send_log_type(CmAttachmentStr),
    lib_mail:send_sys_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, CmAttachmentStr, SendLogType).

%% 拍卖行邮件使用这个（PHP不能调用此函数）
send_auction_mail(PlayerInfoList, ModuleId, Title, Content, CmAttachmentStr) when is_integer(ModuleId) ->
    SendLogType = lib_mail:get_send_log_type(CmAttachmentStr),
    lib_mail:send_auction_mail(PlayerInfoList, ModuleId, ?MOD_NONE, Title, Content, CmAttachmentStr, SendLogType).

send_auction_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, CmAttachmentStr) when is_integer(ModuleId), is_integer(SubModuleId) ->
    SendLogType = lib_mail:get_send_log_type(CmAttachmentStr),
    lib_mail:send_auction_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, CmAttachmentStr, SendLogType).

%% PHP调用需要把附件用 util:string_to_term/1 转化
%% @param CmAttachmentStr string()
%% @param SendLogType 1:记录 0:不记录
send_sys_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, CmAttachmentStr, SendLogType, Important) ->
    lib_mail:send_sys_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, util:string_to_term(CmAttachmentStr), SendLogType, Important).

%% 根据条件发邮件给所有在线玩家
send_sys_mail_online(Title, Content, CmAttachmentStr, Source, LevelLimit, Important, SendLogType) ->
    send_sys_mail_online(Title, Content, CmAttachmentStr, Source, LevelLimit, SendLogType, ?MOD_NONE, ?MOD_NONE, Important).
send_sys_mail_online(Title, Content, CmAttachmentStr, Source, LevelLimit, SendLogType, ModuleId, Important) ->
    send_sys_mail_online(Title, Content, CmAttachmentStr, Source, LevelLimit, SendLogType, ModuleId, ?MOD_NONE, Important).
send_sys_mail_online(Title, Content, CmAttachmentStr, Source, LevelLimit, SendLogType, ModuleId, SubModuleId, Important) ->
    SourceBin = util:make_sure_binary(Source),
    Sql = case SourceBin =/= <<>> of
        true -> io_lib:format(?sql_role_id_by_source_and_onlineflag_and_lv, [SourceBin, 1, LevelLimit]);
        false -> io_lib:format(?sql_role_id_by_onlineflag_and_lv, [1, LevelLimit])
    end,
    case db:get_all(Sql) of
        [] ->
            ok;
        InfoList ->
            PlayerInfoList = lists:flatten(InfoList),
            lib_mail:send_sys_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, util:string_to_term(CmAttachmentStr), SendLogType, Important)
    end.


%% 根据条件发邮件给所有玩家
%% --------------------- 游戏逻辑调用 ---------------------------
send_sys_mail_to_all(Title, Content, CmAttachmentStr, Source, MinLv, MinVip, MaxVip, SendLogType) ->
    send_sys_mail_to_all(Title, Content, CmAttachmentStr, Source, MinLv, ?DEFAULT_MAX_LV, MinVip, MaxVip, ?DEFAULT_LOGIN_DAY, SendLogType, ?MOD_NONE, ?MOD_NONE, ?NOT_IMPORTANT_MAIL).

send_sys_mail_to_all(Title, Content, CmAttachmentStr, Source, MinLv, MinVip, MaxVip, SendLogType, ModuleId) ->
    send_sys_mail_to_all(Title, Content, CmAttachmentStr, Source, MinLv, ?DEFAULT_MAX_LV, MinVip, MaxVip, ?DEFAULT_LOGIN_DAY, SendLogType, ModuleId, ?MOD_NONE, ?NOT_IMPORTANT_MAIL).

send_sys_mail_to_all(Title, Content, CmAttachmentStr, Source, MinLv, MinVip, MaxVip, SendLogType, ModuleId, SubModuleId) ->
    send_sys_mail_to_all(Title, Content, CmAttachmentStr, Source, MinLv, ?DEFAULT_MAX_LV, MinVip, MaxVip, ?DEFAULT_LOGIN_DAY, SendLogType, ModuleId, SubModuleId, ?NOT_IMPORTANT_MAIL).

-spec send_sys_mail_to_all(Title, Content, CmAttachmentStr, Source, MinLv, MaxLv, MinVip, MaxVip, Days, SendLogType, ModuleId, SubModuleId, Important) -> ReturnType when
    Title :: list() | string() | binary(),                   %% 标题
    Content :: list() | string() | binary(),                 %% 内容
    CmAttachmentStr :: string(),                             %% 附件
    Source :: list() | string() | binary() | bitstring(),    %% 渠道
    MinLv :: integer(),                                      %% 最小等级
    MaxLv :: ?DEFAULT_MAX_LV | integer(),                    %% 最大等级
    MinVip :: integer(),                                     %% 最小vip
    MaxVip :: integer(),                                     %% 最大vip
    Days :: ?DEFAULT_LOGIN_DAY | integer(),                  %% 最近多少天登录
    SendLogType :: ?SEND_LOG_TYPE_NO | ?SEND_LOG_TYPE_YES,   %% 日志类型
    ModuleId :: integer(),                                   %% 功能id
    SubModuleId :: integer(),                                %% 功能子id
    Important   :: integer(),                                %% 是否重要邮件
    ReturnType :: term().
send_sys_mail_to_all(Title, Content, CmAttachmentStr, Source, MinLv, MaxLv, MinVip, MaxVip, Days, SendLogType, ModuleId, SubModuleId, Important) ->
    case get_available_sql(Source, MinLv, MaxLv, MinVip, MaxVip, Days) of
        SQL = [_|_] ->
            case db:get_all(SQL) of
                [] -> ok;
                InfoList ->
                    PlayerInfoList   = lists:append(InfoList),
                    CmAttachmentStr1 = util:string_to_term(CmAttachmentStr),
                    spawn(fun() ->
                        batch_send_sys_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, CmAttachmentStr1, SendLogType, Important)
                          end),
                    ok
            end;
        _A ->
            ?ERR("send sys mail error ~p ~p ~w ~p ~p ~p ~p ~p", [ModuleId, SubModuleId, Source, MinLv, MaxLv, MinVip, MaxVip, Days]),
            _A
    end.

batch_send_sys_mail([],_, _, _, _, _, _, _) ->
    ok;
batch_send_sys_mail(RoleIdList= [_|_], ModuleId, SubModuleId, Title, Content, CmAttachmentStr, SendLogType, Important) ->
    Len = length(RoleIdList),
    if Len >= 20 ->
        {SendList, RestList} = lists:split(20, RoleIdList),
        lib_mail:send_sys_mail(SendList, ModuleId, SubModuleId, Title, Content, CmAttachmentStr, SendLogType, Important),
        timer:sleep(250),
        batch_send_sys_mail(RestList, ModuleId, SubModuleId, Title, Content, CmAttachmentStr, SendLogType, Important);
        true ->
            lib_mail:send_sys_mail(RoleIdList, ModuleId, SubModuleId, Title, Content, CmAttachmentStr, SendLogType, Important)
    end.

get_available_sql(Source, MinLv, MaxLv, MinVip, MaxVip, Days) ->
    SourceBin = util:make_sure_binary(Source),
    IsVipLim  = is_vip_limit(MinVip, MaxVip),
    {IsLoginDayLimit, LastLogoutTime}
        = is_login_day_limit(Days),
    %% 默认会有等级判断
    case SourceBin =/= <<>> of
        true -> %% 有渠道限制
            if IsLoginDayLimit andalso IsVipLim -> %% 最近登录天数&VIP
                io_lib:format(?SQL_ROLE_ID_BY_ALL_CON, [LastLogoutTime, MinLv, MaxLv, SourceBin, MinVip, MaxVip]);
                IsLoginDayLimit andalso (not IsVipLim) -> %% 最近登录天数
                    io_lib:format(?SQL_ROLE_ID_BY_LOGIN_DAY, [LastLogoutTime, MinLv, MaxLv, SourceBin]);
                (not IsLoginDayLimit) andalso IsVipLim -> %% VIP
                    io_lib:format(?SQL_ROLE_ID_BY_VIP_AND_LV, [MinLv, MaxLv, SourceBin, MinVip, MaxVip]);
                (not IsLoginDayLimit) andalso (not IsVipLim) -> %% 只有等级限制
                    io_lib:format(?SQL_ROLE_ID_BY_LV, [MinLv, MaxLv, SourceBin]);
                true ->
                    sql_error
            end;
        _ -> %% 无渠道限制
            if IsLoginDayLimit andalso IsVipLim -> %% 最近登录天数&VIP
                io_lib:format(?sql_role_id_by_lv, [MinLv, MaxLv, LastLogoutTime, MinVip, MaxVip]);
                IsLoginDayLimit andalso (not IsVipLim) -> %% 最近登录天数
                    io_lib:format(?SQL_ROLE_ID_BY_DAY_WITHOUT_SOURCE, [LastLogoutTime, MinLv, MaxLv]);
                (not IsLoginDayLimit) andalso IsVipLim -> %% VIP
                    io_lib:format(?SQL_ROLE_ID_BY_VIP_WITHOUT_SOURCE, [MinLv, MaxLv, MinVip, MaxVip]);
                (not IsLoginDayLimit) andalso (not IsVipLim) -> %% 只有等级限制
                    io_lib:format(?SQL_ROLE_ID_BY_LV_WITHOUT_SOURCE, [MinLv, MaxLv]);
                true ->
                    sql_error
            end
    end.

%% Vip参数相等且都为0默认不需要VIP限制
%% 否则则需要VIP限制
is_vip_limit(MinVip, MaxVip) ->
    MinVip =/= MaxVip orelse (MinVip == MaxVip andalso MinVip =/= 0).

%% Days参数为0默认不需要限制最近登录天数
is_login_day_limit(_Days = 0) ->
    {false, 0};
is_login_day_limit(Days) ->
    % MidNight        = utime:unixdate(),
    % LastLogoutTime  = MidNight - (max(0, Days - 1) * ?ONE_DAY_SECONDS),
    LastLogoutTime = utime:that_day_before(max(0, Days - 1)),
    {true, LastLogoutTime}.

%% ---------------------------------------------------------------------------
%% @doc php发邮件给等级大于等于Lev级并且最近Days天有上线的玩家
-spec php_send_sys_mail_to_active(Title, Content, AttachmentStr, Lev, Days, Important, SendLogType) -> ok when
    Title           :: list() | binary(),
    Content         :: list() | binary(),
    AttachmentStr   :: list() | binary(), % [{?TYPE_GOODS|?TYPE_GOOD|?TYPE_BGOLD|?TYPE_GCOIN, GoodsTypeId, Num}],
    Lev             :: integer(),
    Days            :: integer(),
    SendLogType     :: integer(),
    Important        :: integer().
%% ---------------------------------------------------------------------------
php_send_sys_mail_to_active(Title, Content, AttachmentStr, Lev, Days, Important, SendLogType) ->
    % MidNight = utime:unixdate(),
    % LastLogoutTime = MidNight - (max(0, Days - 1) * ?ONE_DAY_SECONDS),
    LastLogoutTime = utime:that_day_before(max(0, Days - 1)),
    Sql = io_lib:format(?sql_role_id_by_lv_and_lastlogouttime, [Lev, LastLogoutTime]),
    case db:get_all(Sql) of
        [] ->
            ok;
        IdList ->
            RoleIdList = lists:flatten(IdList),
            lib_mail:send_sys_mail(RoleIdList,  ?MOD_NONE, ?MOD_NONE, Title, Content, util:string_to_term(AttachmentStr), SendLogType, Important)
    end.

%% ---------------------------------------------------------------------------------
%% @doc 发邮件给等级大于等于Lev级并且最近Days天有上线的玩家,此接口只允许程序内部使用
-spec send_sys_mail_to_active(Title, Content, Attachment, Lev, Days) -> ok when
    Title           :: list() | binary(),
    Content         :: list() | binary(),
    Attachment      :: list() | binary(), % [{?TYPE_GOODS|?TYPE_GOOD|?TYPE_BGOLD|?TYPE_GCOIN, GoodsTypeId, Num}],
    Lev             :: integer(),
    Days            :: integer().
%% ---------------------------------------------------------------------------
send_sys_mail_to_active(Title, Content, Attachment, Lev, Days) ->
    % MidNight = utime:unixdate(),
    % LastLogoutTime = MidNight - (max(0, Days - 1) * ?ONE_DAY_SECONDS),
    LastLogoutTime = utime:that_day_before(max(0, Days - 1)),
    Sql = io_lib:format(?sql_role_id_by_lv_and_lastlogouttime, [Lev, LastLogoutTime]),
    case db:get_all(Sql) of
        [] ->
            ok;
        IdList ->
            RoleIdList = lists:flatten(IdList),
            lib_mail:send_sys_mail(RoleIdList, ?MOD_NONE, ?MOD_NONE, Title, Content, Attachment, ?SEND_LOG_TYPE_NO)
    end.


%% 发送公会邮件
send_guild_mail(PlayerInfoList, Title, Content, CmAttachment) ->
    lib_mail:send_guild_mail(PlayerInfoList, ?MOD_NONE, ?MOD_NONE, Title, Content, ?MAIL_TYPE_GUILD, CmAttachment).
send_guild_mail(PlayerInfoList, ModuleId, Title, Content, CmAttachment) ->
    lib_mail:send_guild_mail(PlayerInfoList, ModuleId, ?MOD_NONE, Title, Content, ?MAIL_TYPE_GUILD, CmAttachment).
send_guild_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, ?MAIL_TYPE_GUILD, CmAttachment) ->
    lib_mail:send_guild_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, ?MAIL_TYPE_GUILD, CmAttachment).

%% 发送公会个人邮件
send_guild_member_mail(PlayerInfoList, Title, Content, CmAttachment) ->
    lib_mail:send_guild_mail(PlayerInfoList, ?MOD_NONE, ?MOD_NONE, Title, Content, ?MAIL_TYPE_GUILD_MEMBER, CmAttachment).
send_guild_member_mail(PlayerInfoList, ModuleId, Title, Content, CmAttachment) ->
    lib_mail:send_guild_mail(PlayerInfoList, ModuleId, ?MOD_NONE, Title, Content, ?MAIL_TYPE_GUILD_MEMBER, CmAttachment).
send_guild_member_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, ?MAIL_TYPE_GUILD_MEMBER, CmAttachment) ->
    lib_mail:send_guild_mail(PlayerInfoList, ModuleId, SubModuleId, Title, Content, ?MAIL_TYPE_GUILD_MEMBER, CmAttachment).

