#ifndef CONNECTORTOSERVER_H
#define CONNECTORTOSERVER_H

#include <QObject>
#include <QMap>
#include <QMutex>
#include <widgets/versionselectwidget.h>
#include "Core\tcpclient.h"
#include "Core\dataparser.h"
#include "Core\sendsystem.h"
#include "Core\recognizesystem.h"
#include "instructor.h"
#include "trainee.h"
#include "group.h"
#include "computer.h"
#include "classroom.h"
#include "streamingversiondata.h"
#include "Datas.h"

class ConnectorToServer : public QObject
{
    Q_OBJECT

public:
    explicit ConnectorToServer(QWidget* parentWidget, QObject *parent = nullptr);
    ~ConnectorToServer();

public:
    ServerSettings getServerSettings();
    bool getIsConnected();

    SendSystem *getSendSystem() const;
    ServerAuthorization getServerAuth(){return serverAuth;}

    void SetConnectToServer();
    void StopConnectToServer();

    void setLoginName(QString name);

public:
    //Send
    bool sendAuthorizationInstructorLocal(QString login, QString password);
    bool sendDeAuthorizationInstructorLocal(QString login);

    bool sendQueryToDB(TypeQueryToDB typeQuery, int id = 0, void* data = nullptr);
    bool sendMessage(ClientMessage clientMessage);

    bool sendQueryTasksXML(QString type);
    bool sendQueryListSubProc(QString dmCode);
    bool sendQueryBlockAuth(bool block);

    void sendShowVersionSelect();
    bool sendClientNotify(QString command);

public:
    //LocalModelDB
    QByteArray getListTaskFimArray();
    QByteArray getListTaskAmmArray();

    QList<Instructor> getListInstructors();
    QList<Trainee> getListTrainees();
    QList<Group> getListGroups();
    QList<Computer> getListComputers();
    QList<Classroom> getListClassrooms();
    QList<TaskAmmFim> getListTasksAMMforTrainee(int trainee_id);
    QList<TaskAmmFim> getListTasksFIMforTrainee(int trainee_id);
    QList<SubProc> getListSubProcForDMCode(QString dmCode);
    int getCountTasksAMMforTrainee(int trainee_id);
    int getCountTasksFIMforTrainee(int trainee_id);

    bool isArchivedInstructor(int id);
    bool isAdminInstructor(int id);
    bool isLoggedInInstructor(int id);
    Instructor getInstructor(int id);

    QList<Trainee> getListTraineesInGroup(int id);
    bool isArchivedTrainee(int id);
    bool isLoggedInTrainee(int id);
    Trainee getTrainee(int id);
    Group getGroup(int id);

    int getIdTraineeByLogin(QString login);
    int getIdInstructorByLogin(QString login);

private:
    //Очистка списочной модели БД СУО
    void clearListModelDB();

public slots:
    //AnswerQueryToDB
    void slot_AnswerQueryToDB_ListInstructors(QList<Instructor> listInstructors);
    void slot_AnswerQueryToDB_ListGroups(QList<Group> listGroups);
    void slot_AnswerQueryToDB_ListTrainees(QList<Trainee> listTrainees);
    void slot_AnswerQueryToDB_ListComputers(QList<Computer> listComputers);
    void slot_AnswerQueryToDB_ListClassrooms(QList<Classroom> listClassrooms);
    void slot_AnswerQueryToDB_ListTasksAMMforTrainee(QList<TaskAmmFim> listTasks, int trainee_id);
    void slot_AnswerQueryToDB_ListTasksFIMforTrainee(QList<TaskAmmFim> listTasks, int trainee_id);
    void slot_AnswerQueryTasksXML_FIM(QByteArray array);
    void slot_AnswerQueryTasksXML_AMM(QByteArray array);
    void slot_AnswerQuerySubProc(QList<SubProc> listSubProc, QString parentTask_dmCode);

    void slot_AnswerDocsChanged();

public slots:
    void slot_sendMessage(ClientMessage clientMessage);
    void slot_showServerList(QList<StreamingVersionData*> *serverList);
    void slot_HashReady();
    void slot_Auth(ServerAuthorization * serverAuth);

signals:
    void sigSetConnect(ServerSettings* serverSettings,QThread *thread);
    void sigStopConnect();
    void sigInitializeClient(RecognizeSystem *recognizeSystem,
                            SendSystem *sendSystem,
                            QThread *thread);    

    void sigLoginResult(ServerAuthorization * serverAuth);
    void sigDeLoginResult(ServerDeAuthorization * serverDeAuth);

    void signal_UpdateDB(bool treeInstructor, bool treeTrainee);

    void signal_UpdateTasksFIM(); //Общий список
    void signal_UpdateTasksAMM(); //Общий список

    void signal_UpdateTasksFIMforTrainee(int trainee_id);
    void signal_UpdateTasksAMMforTrainee(int trainee_id);

    void signal_UpdateSubProcForDMCode(QString dmCode);

    void signal_ConnectedToServer(bool state);

    void signal_reInitMessangerByUsers(QList<User> listUsers);

    void signal_receiveMessage(ClientMessage clientMessage);
    void sigSendAnswerToServer(QByteArray array);

    void signal_AnswerDocsChanged();

private:
    void initialize();
    void bindConnection();
    void createObjects();

private:
    QWidget* parentWidget;
    QThread *connectionThread;
    TCPClient *client;
    DataParser *dataParser;
    SendSystem *sendSystem;
    RecognizeSystem *recognizeSystem;
    VersionSelectWidget *versionSelectWidget;
    VersionContainer *versionContainer;
    NotifyController *notifyController;

    //Списочная модель БД СУО
    QMutex mtxAccess;
    QList<Instructor> listInstructors;    
    QList<Group> listGroups;
    QList<Trainee> listTrainees;
    QList<Computer> listComputers;
    QList<Classroom> listClassrooms;
    QMap<int, QList<TaskAmmFim>> mapTasksAMM;
    QMap<int, QList<TaskAmmFim>> mapTasksFIM;
    QByteArray listTaskFimArray;
    QByteArray listTaskAmmArray;

    QMap<QString, QList<SubProc>> mapSubProc;

    ServerSettings serverSettings;
    ServerAuthorization serverAuth;

    bool fl_GetedOfflineMessages;    
};

#endif // CONNECTORTOSERVER_H
