#pragma once
#include <signal.h>
#include <iostream>
#include "Util/logger.h"
#include "Network/TcpClient.h"
#include "Util/NoticeCenter.h"
#include "Notices.h"
#include <condition_variable>
#include <ctime>
#include <map>
#include <thread>

#include "Util/util.h"
#include "Util/logger.h"
#include "Network/Socket.h"
#include "Util/TimeTicker.h"
#include "Util/NoticeCenter.h"
#include "Poller/Timer.h"

using namespace std;
using namespace toolkit;

#define Request_timeout 4000
#define Internal_Server_Error 500
#define Unauthorized 401
#define Forbiddem 403
#define Request_Time_out 408

class TCPClient:public TcpClient
{
public:
    struct RequestAckTask
    {
        std::shared_ptr<Ticker> ticker = nullptr;
        std::string CommandEnum;
        function<void(int, std::string)> task; // 回调任务
        bool Finish = false;
    };

public:
    typedef std::shared_ptr<TCPClient> Ptr;

    TCPClient():TcpClient() {
    }
    ~TCPClient() {}

    /**
     * @description: 发送请求
     * @param {string} RequestId  UUID
     * @param {string} CommandEnum 命令枚举
     * @param {string&} data  数据
     * @param {function<void(std::string)>} t 回调函数（请求结果, 返回的数据）
     * @return {*}
     */    
    void sendRequest(std::string RequestId,std::string CommandEnum, std::string& data,function<void(int, std::string)> t);

    /**
     * @description: 接收请求响应
     * @param {string&} json
     * @return {*}
     */    
    int requestAck(std::string& json);


protected:
     /**
     * @description: 连接成功时触发
     * @param {SockException} &ex  连接info
     * @return {*}
     * @author: lishengyin
     */   
    virtual void onConnect(const SockException &ex) override;
    /**
     * @description: 接收数据时触发
     * @param {Ptr} &pBuf 接受到的数据
     * @return {*}
     * @author: lishengyin
     */    
    virtual void onRecv(const Buffer::Ptr &pBuf) override;
        /**
     * @description: 发送阻塞时触发
     * @param {*}
     * @return {*}
     * @author: lishengyin
     */  
    virtual void onFlush() override;
    /**
     * @description: EOF时触发
     * @param {SockException} &ex 错误信息
     * @return {*}
     * @author: lishengyin
     */   
    virtual void onErr(const SockException &ex) override;
        /**
     * @description: 心跳 2S触发一次
     * @param {*}
     * @return {*}
     * @author: lishengyin
     */ 
    virtual void onManager() override;

    /**
     * @description: 超时处理
     * @param {*}
     * @return {*}
     */    
    void requestOvertimeWork(std::string requestId, std::string CommandEnum);

    

private:
    int _nTick = 0;
    std::string _IP;
    int32_t _port;

    Buffer::Ptr sbuf = nullptr;
    map<std::string, RequestAckTask> requestTasks;
};