%%%-------------------------------------------------------------------
%%% @author liushl
%%% @doc
%%%     装备任务
%%% @end
%%%-------------------------------------------------------------------
-module(equipment_task).
-author("liushl").

-include("server.hrl").
-include("equipment_check.hrl").
-include("def_goods.hrl").
-include("goods.hrl").
-include("equipment.hrl").
-include("predefine.hrl").
-include("market.hrl").
-include("errcode.hrl").
-include("figure.hrl").
%% API
-export([]).
-compile(export_all).

%% 任务模块-大类
-define(EQUIP_TASK_SHOP,    1).     %% 商店类
-define(EQUIP_TASK_MARKET,  2).     %% 交易类
-define(EQUIP_TASK_COMPOSE, 3).     %% 合成类
%% 任务目标-子类-完成条件
-define(EQUIP_TASK_SHOP_GUARD_NUM,     1).  %% 商店购买守护（累计数量）     [品质，数量]
-define(EQUIP_TASK_SHOP_GOODS_ID,      2).  %% 商店购买某个首饰（指定物品id）[物品id, 数量1]
-define(EQUIP_TASK_MARKET_WORLD_NUM,   3).  %% 世界拍卖某转装备（累计数量）  [转数，数量]
-define(EQUIP_TASK_COMPOSE_GUARD_NUM,  4).  %% 合成守护（累计数量）        [品质，数量]
-define(EQUIP_TASK_COMPOSE_GOODS_ID,   5).  %% 合成某个首饰（指定物品id）   [物品id，数量1]
-define(EQUIP_TASK_MARKET_GUILD_NUM,   6).  %% 公会拍卖装备（累计数量）     [数量]
%% 任务开放条件：[{turn, 转数},{lv, 等级}]
%% 任务进度判断
-define(EQUIP_TASK_FIN_TYPE_1,  1).    %% 类型1：某种条件-进度累积
-define(EQUIP_TASK_FIN_TYPE_2,  2).    %% 类型2：进度累积
%% 任务状态
-define(EQUIP_TASK_STATUS_NONE,  0).
-define(EQUIP_TASK_STATUS_FIN,   1).
-define(EQUIP_TASK_STATUS_AWARD, 2).

%% 登陆初始化
login(RoleId) ->
    SQL = io_lib:format(<<"SELECT task_id,progress,status,time FROM role_equipment_task WHERE role_id=~p">>, [RoleId]),
    Tasks = db:get_all(SQL),
    List =
    [
        {TaskId, #equipment_task{progress = Progress, status = Status, time = Time}}
        || [TaskId, Progress, Status, Time] <- Tasks
    ],
    maps:from_list(List).

%% 获得所有任务
get_all_task_info(Player) ->
    #player_status{equipment_task = AllTask} = Player,
    [
        {TaskId, Progress, Status}
        || {TaskId, #equipment_task{progress = Progress, status = Status}} <- maps:to_list(AllTask)
    ].

%% 给前端刷新一条任务数据
notice_one_task(RoleId, TaskId, #equipment_task{progress = Progress, status = Status}) ->
    lib_server_send:send_to_uid(RoleId, pt_145, 14511, [TaskId, Progress, Status]).

%% 领取任务奖励
get_task_award(Player, TaskId) ->
    #player_status{equipment_task = AllTask, id = RoleId, figure = Figure} = Player,
    TaskInfo = maps:get(TaskId, AllTask, undefied),
    TaskCfg = data_equipment_check:get_equipment_task(TaskId),
    if
        not is_record(TaskInfo, equipment_task) -> {false, ?ERRCODE(err145_task_conditon)};
        not is_record(TaskCfg, base_equipment_task) -> {false, ?MISSING_CONFIG};
        TaskInfo#equipment_task.status =:= ?EQUIP_TASK_STATUS_NONE -> {false, ?ERRCODE(err145_task_conditon)};
        TaskInfo#equipment_task.status =:= ?EQUIP_TASK_STATUS_AWARD -> {false, ?ERRCODE(err145_already_get)};
        true ->
            Now = utime:unixtime(),
%%            case check_task_open(Player, TaskCfg#base_equipment_task.condition) of
%%                {false, Error} -> {false, Error};
%%                true ->
                    TaskInfo1 = TaskInfo#equipment_task{status = ?EQUIP_TASK_STATUS_AWARD, time = Now},
                    save_one_task(RoleId, TaskId, TaskInfo1),
                    notice_one_task(RoleId, TaskId, TaskInfo1),
                    NewAllTask = AllTask#{TaskId => TaskInfo1},
                    Player1 = Player#player_status{equipment_task = NewAllTask},
                    Player2 = lib_goods_api:send_reward(Player1, TaskCfg#base_equipment_task.award, equipment_task),
            RFMT = lib_recharge:get_statistic(Player),
            lib_log_api:log_equipment_task_reward(
                [RoleId, Figure#figure.name, Figure#figure.lv, util:term_to_bitstring(RFMT), util:get_open_day(), TaskId,
                    util:term_to_bitstring(TaskCfg#base_equipment_task.award), Now]
            ),
            {ok, Player2}
%%            end
    end.

%% 保存一条任务数据
save_one_task(RoleId, TaskId, TaskInfo) ->
    #equipment_task{
        progress = Progress,
        status = Status,
        time = Time
    } = TaskInfo,
    SQL = io_lib:format(<<"REPLACE INTO role_equipment_task(role_id,task_id,progress,status,time) VALUES(~p,~p,~p,~p,~p)">>,
        [RoleId, TaskId, Progress, Status, Time]),
    db:execute(SQL),
    ok.
%%%-------------------------------------------------------------------
%%% @doc
%%%     完成任务事件触发
%%% @end
%%%-------------------------------------------------------------------
%% 商店购买物品 lib_shop:381
event_shop_buy(Player, GoodsId) ->
    case data_equipment:get_equipment_info(GoodsId) of
        #base_equipment{equip_type = ?EQUIPMENT_GUARD, color = Color} ->
            Player1 = trigger_task(Player, ?EQUIP_TASK_SHOP_GUARD_NUM, ?EQUIP_TASK_FIN_TYPE_1, [Color, 1]),
            Player1;
        #base_equipment{equip_type = SubType}
            when SubType =:= ?EQUIPMENT_NECKLACE
            orelse SubType =:= ?EQUIPMENT_RINGS
            orelse SubType =:= ?EQUIPMENT_EARRINGS ->
            Player1 = trigger_task(Player, ?EQUIP_TASK_SHOP_GOODS_ID, ?EQUIP_TASK_FIN_TYPE_1, [GoodsId, 1]),
            Player1;
        _ ->
            Player
    end.

%% 市场拍卖 market_mgr:1241
event_market_buy(RoleId, MarketType, GoodsId) ->
    case lib_player:apply_cast(RoleId, ?APPLY_CAST_STATUS, ?MODULE, event_market_buy_check, [MarketType, GoodsId]) of
        skip ->
            event_market_buy_check(RoleId, MarketType, GoodsId);
        _ ->
            ok
    end.
event_market_buy_check(RoleInfo, MarketType, GoodsId) ->
    case data_equipment:get_equipment_info(GoodsId) of
        #base_equipment{series = Series} when MarketType =:= ?MARKET_SELL_TYPE_WORLD ->
            trigger_task(RoleInfo, ?EQUIP_TASK_MARKET_WORLD_NUM, ?EQUIP_TASK_FIN_TYPE_1, [Series, 1]);
        #base_equipment{} when MarketType =:= ?MARKET_SELL_TYPE_GUILD ->
            trigger_task(RoleInfo, ?EQUIP_TASK_MARKET_GUILD_NUM, ?EQUIP_TASK_FIN_TYPE_2, [1]);
        _ ->
            RoleInfo
    end.

%% 装备合成 equipment_api:825
event_equipment_evolution(Player, #goods{goods_id = GoodsId}) ->
    event_equipment_evolution(Player, GoodsId);
event_equipment_evolution(Player, GoodsId) ->
    case data_equipment:get_equipment_info(GoodsId) of
        #base_equipment{equip_type = ?EQUIPMENT_GUARD, color = Color} ->
            Player1 = trigger_task(Player, ?EQUIP_TASK_COMPOSE_GUARD_NUM, ?EQUIP_TASK_FIN_TYPE_1, [Color, 1]),
            Player1;
        #base_equipment{equip_type = SubType}
            when SubType =:= ?EQUIPMENT_NECKLACE
            orelse SubType =:= ?EQUIPMENT_RINGS
            orelse SubType =:= ?EQUIPMENT_EARRINGS ->
            Player1 = trigger_task(Player, ?EQUIP_TASK_COMPOSE_GOODS_ID, ?EQUIP_TASK_FIN_TYPE_1, [GoodsId, 1]),
            Player1;
        _ ->
            Player
    end.
%%%-------------------------------------------------------------------
%% 在线触发任务
trigger_task(Player, TaskType, FinType, Arg) when is_record(Player, player_status) ->
    #player_status{equipment_task = AllTask, id = RoleId} = Player,
    NewAllTask = trigger_task_do(Player, RoleId, AllTask, TaskType, FinType, Arg),
    Player#player_status{equipment_task = NewAllTask};
%% 离线触发任务
trigger_task(RoleId, TaskType, FinType, Arg) ->
    AllTask = login(RoleId),
    trigger_task_do(RoleId, RoleId, AllTask, TaskType, FinType, Arg).

%% 触发任务
trigger_task_do(RoleInfo, RoleId, AllTask, TaskType, FinType, Arg) ->
    %% 找到该任务类型的所有任务id
    AllTaskId  = data_equipment_check:get_all_tasks_by_type(TaskType),
    %% 一个一个的判断刷新任务
    NewAllTask = trigger_each_task(RoleInfo, RoleId, AllTask, AllTaskId, FinType, Arg),
    NewAllTask.

trigger_each_task(_RoleInfo, _RoleId, AllTask, [], _, _) -> AllTask;
trigger_each_task(RoleInfo, RoleId, AllTask, [TaskId|T], FinType, Arg) ->
    TaskInfo = maps:get(TaskId, AllTask, #equipment_task{}),
    Config   = data_equipment_check:get_equipment_task(TaskId),
    NewAllTask =
        case deal_with_task(Config, TaskId, TaskInfo, FinType, Arg) of
            TaskInfo1 when is_record(TaskInfo1, equipment_task) ->
                Now = utime:unixtime(),
                TaskInfo2 = TaskInfo1#equipment_task{time = Now},
                AllTask1 = AllTask#{TaskId => TaskInfo2},
                notice_one_task(RoleId, TaskId, TaskInfo2),
                save_one_task(RoleId, TaskId, TaskInfo2),
                case RoleInfo of
                    #player_status{figure = Figure} ->
                        RFMT = lib_recharge:get_statistic(RoleInfo);
                    _ ->
                        Figure = lib_role:get_role_figure(RoleId),
                        RFMT = offline
                end,
                lib_log_api:log_equipment_task([
                    RoleId, Figure#figure.name, Figure#figure.lv, util:term_to_bitstring(RFMT), TaskId, TaskInfo1#equipment_task.progress,
                    util:term_to_bitstring(Config#base_equipment_task.content), Now
                ]),
                AllTask1;
            _R ->
                %% 任务已经完成，或者出现了错误
                AllTask
        end,
    trigger_each_task(RoleInfo, RoleId, NewAllTask, T, FinType, Arg).

%% @doc 任务统一处理
%% 某种条件-进度累积
deal_with_task(
    #base_equipment_task{content = [Condition, Target], task_id = TaskId},
    TaskId,
    #equipment_task{status = ?EQUIP_TASK_STATUS_NONE, progress = Progress} = TaskInfo,
    ?EQUIP_TASK_FIN_TYPE_1,
    [DataCondition, Add]
) when Condition =:= DataCondition andalso is_integer(Add) andalso Add > 0 ->
    Now = Progress + Add,
    case Now >= Target of
        true  -> TaskInfo#equipment_task{progress = Target, status = ?EQUIP_TASK_STATUS_FIN};
        false -> TaskInfo#equipment_task{progress = Now, status = ?EQUIP_TASK_STATUS_NONE}
    end;
%% 进度累积
deal_with_task(
    #base_equipment_task{content = [Target], task_id = TaskId},
    TaskId,
    #equipment_task{status = ?EQUIP_TASK_STATUS_NONE, progress = Progress} = TaskInfo,
    ?EQUIP_TASK_FIN_TYPE_2,
    [Add]
) when is_integer(Add) andalso Add > 0 ->
    Now = Progress + Add,
    case Now >= Target of
        true  -> TaskInfo#equipment_task{progress = Target, status = ?EQUIP_TASK_STATUS_FIN};
        false -> TaskInfo#equipment_task{progress = Now, status = ?EQUIP_TASK_STATUS_NONE}
    end;
deal_with_task(_, _, _, _, _) ->
    none.

%% 判断任务是否开放
check_task_open(_Player, []) -> true;
check_task_open(Player, [{turn, Turn}|T]) ->
    RoleTurn = transform:get_transform_id(Player),
    case RoleTurn >= Turn of
        true  ->
            check_task_open(Player, T);
        false ->
            {false, ?ERRCODE(err145_turn_lower)}
    end;
check_task_open(Player, [{lv, Lv}|T]) ->
    RoleLv = lib_player:get_lv(Player),
    case RoleLv >= Lv of
        true  ->
            check_task_open(Player, T);
        false ->
            {false, ?ERRCODE(err145_lv_lower)}
    end.