#include "floatForm.h"
#include "ui_floatForm.h"
#include <QPixmap>
#include "base/config/configManger.h"
#include "preDefine.h"
#include "QsLog.h"
#include <QProcess>
#include <QThread>
#include <QHostInfo>
#include <QUdpSocket>
#include <QByteArray>
#include <QJsonObject>
#include <QJsonDocument>
#include <QDesktopWidget>
#include <QPoint>

#include "event/fmapplication.h"
#include "event/posevent.h"
#include "model/posorderpool.h"


extern QThread  workThread;

FloatForm::FloatForm(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::FloatForm)
{
    ui->setupUi(this);

    m_is_login = false;

    FMApplication::subscibeEvent(this, PosEvent::s_change_order);
    FMApplication::subscibeEvent(this, PosEvent::s_show_float);
    FMApplication::subscibeEvent(this, PosEvent::s_delete_order);
    FMApplication::subscibeEvent(this, PosEvent::s_login_status);
    FMApplication::subscibeEvent(this, PosEvent::s_network_outtime);
    FMApplication::subscibeEvent(this, PosEvent::s_pickuporder_remind);

    m_bReminding = false;

    QPixmap imgNormal(":loginlogin.png");
    m_imgNormalSize = imgNormal.size();
    QPixmap imgRemind(":loginlogin.png");
    m_imgRemindSize = imgRemind.size();

    m_animation.setTargetObject(this);
    m_animation.setPropertyName("windowOpacity");
    m_animation.setDuration(ConfigManger::GetInstance().GetBlinkInterval());
    m_animation.setEasingCurve(QEasingCurve::InOutSine);
    m_raiseTimer.setInterval(2000);
    connect(&m_raiseTimer, &QTimer::timeout, this, &FloatForm::raise);
    desktopSize= QApplication::desktop()->screenGeometry().size();
    desktopSize-= QSize(242, 100);

    //界面数据初始化
    ui->label_newnum->setText("0");
    ui->label_refundnum->setText("0");

    //设置拖动图层透明度
    ui->widget_touch->setWindowOpacity(0.1);

    _Init();
}

FloatForm::~FloatForm()
{
    delete ui;
}

void FloatForm::InitWidget(int flag)
{
    if(flag == -1)
    {
        if(m_is_login)
        {
            ui->widget_base->show();
            ui->widget_login->hide();
            ui->widget_synshow->hide();
        }
        else
        {
            ui->widget_base->show();
            ui->widget_login->hide();
            ui->widget_synshow->hide();
        }
        return ;
    }
}

bool FloatForm::event(QEvent *e)
{
    if(e->type() == PosEvent::s_change_order)
    {
        QString orderid;

        GETEVENTINFO(orderid,e,QString);

        int refundstatus, orderstatus, ordertype;
        bool oldorder;

        int tk_new = 0, tk_make = 0, tk_send = 0, tk_refund = 0;
        int self_new = 0, self_make = 0, self_refund = 0;

        PosOrderPool::GetOrderNum(tk_new, tk_make, tk_send, tk_refund, self_new, self_make, self_refund);

        QLOG_DEBUG() << "tk_new" << tk_new << "tk_make" << tk_make << "tk_send" << tk_send << "self_new" << self_new << "self_make" << self_make;
        QLOG_DEBUG() << "tk_refund" << tk_refund << "self_refund" << self_refund;

        ui->label_newnum->setText(QString::number(tk_new + self_new + tk_make + self_make));
        ui->label_refundnum->setText(QString::number(self_refund + tk_refund));

        if(!PosOrderPool::GetOrderStatusAndOrderType(orderid, orderstatus, refundstatus, ordertype, oldorder))
            return true;
        //预约单不在提醒
        if(ordertype == AppointmentTakeout || ordertype == AppointmentDining || ordertype == AppointmentInvite)
            return true;

        QLOG_DEBUG() << "input : " << orderid << orderstatus << refundstatus << oldorder;

        QString configfile = qApp->applicationDirPath() + "/" + CONFIG_NAME;
        QString autoconf = QSettings(configfile, QSettings::IniFormat).value(INI_AUTOCONFIRM, "0").toString();

        if(!oldorder && ((orderstatus == NewOrder && autoconf.toInt() == 0) || (orderstatus == FirmOrder && autoconf.toInt() == 1)) &&
                refundstatus != ApplicationRefundOrder && refundstatus != ApplicationPartialRefundOrder && refundstatus != RefusingRefundOrder)
        {
            m_play_flag = false;
            if(ui->widget_synshow->isHidden())
                ui->widget_synshow->show();
            onStartRemind(0);
            return true;
        }

        if((refundstatus == ApplicationRefundOrder || refundstatus == ApplicationPartialRefundOrder))
        {
            m_play_flag = false;
            if(ui->widget_synshow->isHidden())
                ui->widget_synshow->show();
            onStartRemind(1);
            return true;
        }

        return true;
     }

     if(e->type() == PosEvent::s_show_float)
     {
         this->onShow();
         return true;
     }

     if(e->type() == PosEvent::s_network_outtime)
     {
        if(!this->isHidden())
        {
            QVariantMap value;
            GETEVENTINFO(value,e,QVariantMap);
            if(value.contains(EVENT_KEY_NETWORKSTATUS) && value[EVENT_KEY_NETWORKSTATUS].toBool() == true)
            {
                this->onStopRemind();
            }
            else
            {
                m_play_flag = true;
                if(ui->widget_synshow->isHidden())
                    ui->widget_synshow->show();
                onStartRemind(2);
            }
        }

        return true;
     }

     if(e->type() == PosEvent::s_delete_order)
     {
         int tk_new = 0, tk_make = 0, tk_send = 0, tk_refund = 0;
         int self_new = 0, self_make = 0, self_refund = 0;

         PosOrderPool::GetOrderNum(tk_new, tk_make, tk_send, tk_refund, self_new, self_make, self_refund);

         QLOG_DEBUG() << "tk_new" << tk_new << "tk_make" << tk_make << "tk_send" << tk_send << "self_new" << self_new << "self_make" << self_make;
         QLOG_DEBUG() << "tk_refund" << tk_refund << "self_refund" << self_refund;

         ui->label_newnum->setText(QString::number(tk_new + self_new + tk_make + self_make));
         ui->label_refundnum->setText(QString::number(self_refund + tk_refund));

         return true;
     }

     if(e->type() == PosEvent::s_login_status)
     {
         QVariantMap value;

         GETEVENTINFO(value,e,QVariantMap);

         if(value.contains(EVENT_KEY_STATUS) && value[EVENT_KEY_STATUS].toBool() == true)
         {
             m_is_login = true;
         }
         return true;
     }
     //预约单提醒
     if(e->type() == PosEvent::s_pickuporder_remind)
     {
         QString orderid;

         GETEVENTINFO(orderid,e,QString);

         QLOG_DEBUG() << "pickuporderremind : " << orderid;

         m_play_flag = false;
         if(ui->widget_synshow->isHidden())
             ui->widget_synshow->show();
         onStartRemind(0);
         return true;
     }

    return QWidget::event(e);
}

void FloatForm::mouseMoveEvent(QMouseEvent *event)
{
    if ((event->buttons()==Qt::LeftButton) && m_bMousePress)
    {
        QSize tmpdesktopSize= QApplication::desktop()->screenGeometry().size();
        if(!m_is_login)
            tmpdesktopSize-= QSize(ui->widget_base->width(), ui->widget_base->height());
        else
            tmpdesktopSize-= QSize(ui->widget_base->width(), ui->widget_base->height());



        QPoint moveAmount = event->globalPos() - m_lastMousePos;
        m_absMove += moveAmount;
        int x=0,y=0;
        x=pos().x()+moveAmount.x();
        y=pos().y()+moveAmount.y();
        if(x>tmpdesktopSize.width()){x=tmpdesktopSize.width();}
        if(x<0){x=0;}
        if(y>tmpdesktopSize.height()){y=tmpdesktopSize.height();}
        if(y<0){y=0;}
        move(x,y);
        m_lastMousePos = event->globalPos();
        m_bMouseMove = true;
    }
}

void FloatForm::mousePressEvent(QMouseEvent *event)
{
    if (event->button()==Qt::LeftButton)
    {
        m_bMousePress = true;
        m_lastMousePos = event->globalPos();
        m_absMove = QPoint(0,0);
    }
}

void FloatForm::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button()==Qt::LeftButton)
    {
        m_bMousePress = false;
    }

    int x = m_absMove.x();
    int y = m_absMove.y();

    if(!m_bMouseMove || (((x>-10)&&(x<10))&&((y>-10)&&(y<10))))
    {
        //qDebug() << "x:" << event->x() << "y:" << event->y();

        if(event->x() > 100 || !m_is_login)
        {
            hide();
            m_raiseTimer.stop();

            if(m_bReminding)
            {
                this->onStopRemind();
            }
            DEFAULTPOSTEVENT(PosEvent::s_show_login, "");
        }
        else
        {
            if(ui->widget_synshow->isHidden() && m_is_login)
            {
                ui->widget_synshow->show();
                if(!ui->widget_base->isHidden())
                    ui->widget_base->hide();
            }
            else if(!ui->widget_synshow->isHidden() && m_is_login)
            {
                ui->widget_synshow->hide();
                if(ui->widget_base->isHidden())
                    ui->widget_base->show();
            }

        }

    }

    m_bMouseMove = false;
    ConfigManger::GetInstance().setFloatInitPostion(this->pos());
}

void FloatForm::_Init()
{
    QSize tmpdesktopSize= QApplication::desktop()->screenGeometry().size();
    if(!m_is_login)
        tmpdesktopSize-= QSize(ui->widget_base->width(), ui->widget_base->height());
    else
        tmpdesktopSize-= QSize(this->width(), this->height());

    setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool);
    setAttribute(Qt::WA_TranslucentBackground);

    setFixedSize(m_imgNormalSize);
    setStyleSheet("#floatWdg{ border-image: url(:float_normal.png); }");

    move(ConfigManger::GetInstance().GetFloatInitPostion());

    QPoint pos=ConfigManger::GetInstance().GetFloatInitPostion();

    if(pos.x()<0)
    {
        pos.setX(0);
    }
    if(pos.y()<0)
    {
        pos.setY(0);
    }
    if(pos.x()>tmpdesktopSize.width())
    {
        pos.setX(tmpdesktopSize.width());
    }
    if(pos.y()>tmpdesktopSize.height())
    {
        pos.setY(tmpdesktopSize.height());
    }
    move(pos);
}

void FloatForm::_Blink()
{
    QEventLoop loop;
    connect(&m_animation, &QPropertyAnimation::finished, &loop, &QEventLoop::quit);
    m_animation.setStartValue(1);
    m_animation.setEndValue(0);
    m_animation.start();
    loop.exec();
    this->setFixedSize(m_imgRemindSize);
    //ui->floatWdg->setStyleSheet("#floatWdg{ border-image: url(:float_remind.png)}");
    //ui->widget_login->show();
    ui->widget_base->hide();
    ui->widget_synshow->hide();
    ui->widget_login->show();
    m_animation.setStartValue(0);
    m_animation.setEndValue(1);
    m_animation.start();
    loop.exec();
    m_animation.setStartValue(1);
    m_animation.setEndValue(0);
    m_animation.start();
    loop.exec();
    this->setFixedSize(m_imgNormalSize);
    //ui->floatWdg->setStyleSheet("#floatWdg{ border-image: url(:float_normal.png)}");
    ui->widget_base->hide();
    ui->widget_synshow->show();
    ui->widget_login->hide();
    m_animation.setStartValue(0);
    m_animation.setEndValue(1);
    m_animation.start();
    loop.exec();

    if(m_bReminding)
    {
        QTimer::singleShot(ConfigManger::GetInstance().GetBlinkInterval(), this, &FloatForm::_Blink);
    }
}

void FloatForm::_PlayWav()
{
    if(m_play_flag == false && m_bReminding == true)
        QSound::play(m_remindWav);
    if(m_bReminding)
    {
        QTimer::singleShot(m_wavPlayInterval, this, &FloatForm::_PlayWav);
    }
}

void FloatForm::_UdpRadio(QString songName, int type,int time)
{
    QJsonObject json;
    json.insert("reqType",type);
    json.insert("sound_name",songName);
    json.insert("time",time);
    static QString ipAddress;
    if(ipAddress.isEmpty())
    {
        QHostInfo info = QHostInfo::fromName(QHostInfo::localHostName());
        foreach(QHostAddress address,info.addresses())
        {
            if(address.protocol() == QAbstractSocket::IPv4Protocol)
            {
                ipAddress=address.toString();
            }
        }
    }
    int port=ConfigManger::GetInstance().GetUdpPort();
    QHostAddress mcast_addr(ipAddress.replace(10,3,ConfigManger::GetInstance().GetUdpUrl()));
    QLOG_INFO()<<"udp info"<<mcast_addr<<port<<QJsonDocument(json).toJson(QJsonDocument::Compact);
    QUdpSocket udp_socket;
    //udp_socket.writeDatagram(QJsonDocument(json).toJson(QJsonDocument::Compact), mcast_addr, port);
    udp_socket.writeDatagram(QJsonDocument(json).toJson(QJsonDocument::Compact), QHostAddress::Broadcast, port);
    udp_socket.waitForBytesWritten();
    udp_socket.close();
    qDebug()<<__FUNCTION__;
}

void FloatForm::onStartRemind(int type)
{
    switch(type)
    {
    case 0:
        m_remindWav = QString("%1/wav/msg.wav").arg(QApplication::applicationDirPath());
        // 加上音频的时长
        m_wavPlayInterval = ConfigManger::GetInstance().GetSoundInterval() + VALUE_NEWORDERTIME;
        ui->label_newmsg->setText(QString::fromLocal8Bit("您有新的订单了!\r\n点击打开查看订单!"));
        break;
    case 1:
        m_remindWav = QString("%1/wav/msg1.wav").arg(QApplication::applicationDirPath());
        m_wavPlayInterval = ConfigManger::GetInstance().GetSoundInterval() + VALUE_REFUNDORDERTIME;
        ui->label_newmsg->setText(QString::fromLocal8Bit("您有新的退单了!\r\n点击打开查看订单!"));
        break;
    case 2:
        ui->label_newmsg->setText(QString::fromLocal8Bit("网络异常!"));
    }

    if(m_bReminding)
    {
        return;
    }else
    {
       m_bReminding = true;
    }

    if(m_remindTimer.isActive())
        m_remindTimer.stop();
    if(this->isHidden())
        m_remindTimer.start(1*1000);
    else
        m_remindTimer.start(7*24*60*60*1000);
    m_remindTimer.setSingleShot(true);
    connect(&m_remindTimer, &QTimer::timeout, this, &FloatForm::onStopRemind);
    _Blink();
    _PlayWav();
}

void FloatForm::onStopRemind()
{
    m_bReminding = false;
    m_play_flag = false;
}

void FloatForm::onShow()
{
    InitWidget();
    show();
    m_raiseTimer.start();
}
