#pragma once
#include <unordered_map>
#include <optional>
#include <nlohmann/json.hpp>
#include "worker.h"

class UndergroundWorker final: public Worker{
    using Row = std::unordered_map<std::string,std::string>;
    struct HouseConditions { int id; int roof; int floor; int wall; int windowc; };
public:
    UndergroundWorker(ConnectionPool& pool,MessageBroker& broker):Worker(pool,broker,"UndergroundWorker"){}
    ~UndergroundWorker() override;

protected:
    void run() override;

private:
    void tick();
    std::vector<Row> fetchPending();
    nlohmann::json executeRow(const Row& r);
    nlohmann::json handleTask(const std::string& type,int performerId,int victimId,const std::string& paramsJson);
    nlohmann::json spyIn(int performerId,int victimId,const nlohmann::json& p);
    nlohmann::json assassin(int performerId,int victimId,const nlohmann::json& p);
    nlohmann::json sabotage(int performerId,int victimId,const nlohmann::json& p);
    nlohmann::json corruptPolitician(int performerId,int victimId,const nlohmann::json& p);
    nlohmann::json rob(int performerId,int victimId,const nlohmann::json& p);
    void updateResult(int id,const nlohmann::json& result);

    nlohmann::json sabotageHouse(int performerId,int victimId,const nlohmann::json& p);
    nlohmann::json sabotageStorage(int performerId,int victimId,const nlohmann::json& p);

    int getUserIdForCharacter(int characterId);
    std::optional<HouseConditions> getHouseByUser(int userId);
    void updateHouse(const HouseConditions& h);
    std::vector<Row> selectStockByBranch(int branchId);
    std::vector<Row> filterByStockTypes(const std::vector<Row>& rows,const std::vector<int>& allowed);
    void updateStockQty(int id,long long qty);
    static int randomInt(int lo,int hi);
    static long long randomLL(long long lo,long long hi);
    static std::vector<size_t> randomIndices(size_t n,size_t k);
    static double randomDouble(double lo,double hi);

private:
    static constexpr const char* Q_SELECT_BY_PERFORMER=R"SQL(
        SELECT u.id, t.tr AS underground_type, u.performer_id, u.victim_id,
               to_char(u.created_at,'YYYY-MM-DD"T"HH24:MI:SS"Z"') AS created_at,
               COALESCE(u.parameters::text,'{}') AS parameters,
               COALESCE(u.result::text,'null')   AS result_text
        FROM falukant_data.underground u
        JOIN falukant_type.underground t ON t.tr=u.underground_type_id
        WHERE u.performer_id=$1
        ORDER BY u.created_at DESC
    )SQL";
    static constexpr const char* Q_SELECT_PENDING=R"SQL(
        SELECT u.id,t.tr AS underground_type,u.performer_id,u.victim_id,COALESCE(u.parameters::text,'{}') AS parameters
        FROM falukant_data.underground u
        JOIN falukant_type.underground t ON t.tr=u.underground_type_id
        WHERE u.result IS NULL AND u.created_at<=NOW()-INTERVAL '1 day'
        ORDER BY u.created_at ASC
        LIMIT 200
    )SQL";
    static constexpr const char* Q_UPDATE_RESULT=R"SQL(
        UPDATE falukant_data.underground SET result=$2::jsonb,updated_at=NOW() WHERE id=$1
    )SQL";
    static constexpr const char* Q_SELECT_CHAR_USER=R"SQL(
        SELECT user_id FROM falukant_data."character" WHERE id=$1
    )SQL";
    static constexpr const char* Q_SELECT_HOUSE_BY_USER=R"SQL(
        SELECT id, roof_condition, floor_condition, wall_condition, window_condition
        FROM falukant_data.user_house
        WHERE user_id=$1
        LIMIT 1
    )SQL";
    static constexpr const char* Q_UPDATE_HOUSE=R"SQL(
        UPDATE falukant_data.user_house
        SET roof_condition=$2, floor_condition=$3, wall_condition=$4, window_condition=$5
        WHERE id=$1
    )SQL";
    static constexpr const char* Q_SELECT_STOCK_BY_BRANCH=R"SQL(
        SELECT id, stock_type_id, quantity
        FROM falukant_data.stock
        WHERE branch_id=$1
        ORDER BY quantity DESC
    )SQL";
    static constexpr const char* Q_UPDATE_STOCK_QTY=R"SQL(
        UPDATE falukant_data.stock SET quantity=$2 WHERE id=$1
    )SQL";
    static constexpr const char* Q_SELECT_CHAR_HEALTH=R"SQL(
        SELECT health FROM falukant_data."character" WHERE id=$1
    )SQL";
    static constexpr const char* Q_UPDATE_CHAR_HEALTH=R"SQL(
        UPDATE falukant_data."character" SET health=$2, updated_at=NOW() WHERE id=$1
    )SQL";
    static constexpr const char* Q_SELECT_FALUKANT_USER=R"SQL(
        SELECT id, money, COALESCE(main_branch_region_id,0) AS main_branch_region_id
        FROM falukant_data.falukant_user
        WHERE user_id=$1
        LIMIT 1
    )SQL";

};
