#ifndef MODULE_AREA_H
#define MODULE_AREA_H

/**
 * @brief 与区域相关的业务模块总接口
 * @author 戴月腾
 * @date 2018-08-25
 */

#include"area.h"
#include"module_const.h"
#include"module_web.h"

#include"module_attendance_vehicle.h"
#include"module_area_over_count.h"
#include"module_area_timeout.h"

class module_area: public singleton_base<module_area>
{
private:
    friend class singleton_base<module_area>;
    module_area()
    {
    }

public:
    static void on_enter(uint32_t card_id,std::shared_ptr<area_hover>&c, int32_t type)
    {
        if(0==c->id() || 0==c->mapid())
        {
            log_error("(0==c->id() || 0==c->mapid()), card_id=%d, 卡type=%d，areaid=%d，mapid=%d",
                      card_id, type, c->id(), c->mapid());
            return;
        }

        auto card_ptr=card_list::instance()->get(tool_other::type_id_to_u64(type, card_id));
        if(!card_ptr)
        {
            log_error("卡不存在card_id=%d", card_id);
            return;
        }

        c->m_enter_time = tool_time::now_to_seconds();

        if(card_ptr->is_person())//统计人卡
        {
            c->m_area->m_person_count++;
        }

        if(card_ptr->is_vehicle())//统计车卡
        {
            c->m_area->m_vehicle_count++;
            //车卡考勤
            module_attendance_vehicle::instance()->on_enter(card_ptr, c);
        }

        //区域超员
        module_area_over_count::instance()->on_enter(card_ptr, c);
        //区域超时
        module_area_timeout::instance()->on_enter(card_ptr, c);

        save_his_area_location_enter(card_ptr);
    }

    static void on_hover(uint32_t card_id,std::shared_ptr<area_hover>&c, int32_t type)
    {
        if(0==c->id() || 0==c->mapid())
        {
            log_error("(0==c->id() || 0==c->mapid()), card_id=%d, 卡type=%d，areaid=%d，mapid=%d",
                      card_id, type, c->id(), c->mapid());
            return;
        }

        auto card_ptr=card_list::instance()->get(tool_other::type_id_to_u64(type, card_id));
        if(!card_ptr)
        {
            log_error("卡不存在card_id=%d", card_id);
            return;
        }

        //        if(card_ptr->is_person())//人卡
        //        {

        //        }

        //        if(card_ptr->is_vehicle())//车卡
        //        {

        //        }

        //区域超时
        module_area_timeout::instance()->on_hover(card_ptr, c);
    }

    static void on_leave(uint32_t card_id, std::shared_ptr<area_hover>&c, int32_t type)
    {
        if(0==c->id() || 0==c->mapid())
        {
            log_error("(0==c->id() || 0==c->mapid()), card_id=%d, 卡type=%d，areaid=%d，mapid=%d",
                      card_id, type, c->id(), c->mapid());
            return;
        }

        auto card_ptr=card_list::instance()->get(tool_other::type_id_to_u64(type, card_id));
        if(!card_ptr)
        {
            log_error("卡不存在card_id=%d", card_id);
            return;
        }

        if(card_ptr->is_person())//统计人卡
        {
            c->m_area->m_person_count--;
        }

        if(card_ptr->is_vehicle())//统计车卡
        {
            c->m_area->m_vehicle_count--;
        }

        //区域超员
        module_area_over_count::instance()->on_leave(card_ptr, c);
        //区域超时
        module_area_timeout::instance()->on_leave(card_ptr, c);

        save_his_area_location_leave(card_ptr);
    }

    ///入库
    static void save_his_area_location_enter(const std::shared_ptr<card_location_base> card_ptr)
    {
        auto area_hover_ptr = card_ptr->get_area_hover();

        char sql[LENGTH_SQL] = {0};

        std::string call("add_area_staff");
        if(card_ptr->is_vehicle())//车卡
        {
            call="add_area_vehicle";
        }

        std::string start_str = tool_time::to_str_ex(static_cast<uint64_t>(area_hover_ptr->m_enter_time) *1000);

        sprintf(sql, "CALL %s(%s, %d, %d, %d, '%s','%s');", call.c_str(),
                tool_other::type_id_to_str(card_ptr->m_type, card_ptr->m_id).c_str(),
                card_ptr->m_id, area_hover_ptr->id(), area_hover_ptr->mapid(), start_str.c_str(), start_str.c_str());

        db_tool::PushAsync(sql);
    }

    ///入库
    static void save_his_area_location_leave(const std::shared_ptr<card_location_base> card_ptr)
    {
        auto area_hover_ptr = card_ptr->get_area_hover();

        char sql[LENGTH_SQL] = {0};

        std::string call("add_area_staff");
        if(card_ptr->is_vehicle())//车卡
        {
            call="add_area_vehicle";
        }

        std::string start_str = tool_time::to_str_ex(static_cast<uint64_t>(area_hover_ptr->m_enter_time) *1000);
        std::string end_str = tool_time::to_str_ex(tool_time::now_to_ms());

        sprintf(sql, "CALL %s(%s, %d, %d, %d, '%s','%s');", call.c_str(),
                tool_other::type_id_to_str(card_ptr->m_type, card_ptr->m_id).c_str(),
                card_ptr->m_id, area_hover_ptr->id(), area_hover_ptr->mapid(), start_str.c_str(), end_str.c_str());

        db_tool::PushAsync(sql);
    }
};

#endif // MODULE_AREA_H
