#ifndef ANSANOMALIB_H
#define ANSANOMALIB_H
#pragma once
#include "ANSEngineCommon.h"
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <openvino/openvino.hpp>
namespace ANSCENTER 
{
    class ANSENGINE_API ANSANOMALIB :public ANSODBase
    {
    public:
        virtual bool Initialize(std::string licenseKey, ModelConfig modelConfig, const std::string& modelZipFilePath, const std::string& modelZipPassword, std::string& labelMap) override;
        virtual bool LoadModel(const std::string& modelZipFilePath, const std::string& modelZipPassword) override;
        virtual bool LoadModelFromFolder(std::string licenseKey, ModelConfig modelConfig, std::string modelName, std::string className, const std::string& modelFolder, std::string& labelMap)override;
        virtual bool OptimizeModel(bool fp16, std::string& optimizedModelFolder);
        std::vector<Object> RunInference(const cv::Mat& input);
        std::vector<Object> RunInference(const cv::Mat& input, const std::string& camera_id);

        bool Destroy();
        ~ANSANOMALIB();
    private:
        bool _openvinoPreprocess;                   
        bool _efficientAd;                          
        MetaData _meta{};                            
        ov::CompiledModel _compiledModel;           
        ov::InferRequest _inferRequest;             
        std::vector<ov::Output<const ov::Node>> _inputs;
        std::vector<ov::Output<const ov::Node>> _outputs;
        std::string     _modelFilePath;
        std::string     _metaFilePath;
        std::string     _device = "CPU";

    private:
        void InitModel(std::string& model_path, std::string& meta_path, std::string& device, bool openvinoPreprocess, bool efficientAd = false);
        void GetModel(std::string& model_path, std::string& device);
        void WarmUp();
        Object Inference(cv::Mat& image);
        Object InferenceSingleImage(cv::Mat& image);
        void InferenceMultiImages(std::string& imageDir, std::string& saveDir);
        std::vector<cv::String> GetImagePaths(std::string& path);
        cv::Mat ReadImage(std::string& path);
        void SaveScoreAndImages(float score, cv::Mat image, cv::String& imagePath, std::string& saveDir);
        cv::Mat PreProcess(cv::Mat& image, MetaData& meta, bool efficientAd = false);
        cv::Mat NormalizeMinMax(cv::Mat& targets, float threshold, float minVal, float maxVal);
        std::vector<cv::Mat> PostProcess(cv::Mat& anomalyMap, cv::Mat& predScore, MetaData& meta);
        cv::Mat SuperimposeAnomalyMap(cv::Mat& anomalyMap, cv::Mat& originImage);
        cv::Mat AddLabel(cv::Mat& mixedImage, float score, int font = cv::FONT_HERSHEY_PLAIN);
        cv::Mat ComputeMask(cv::Mat& anomalyMap, float threshold = 0.5, int kernelSize = 1);
        cv::Mat GenMaskBorder(cv::Mat& mask, cv::Mat& image);
        std::vector<cv::Mat> GenImages(cv::Mat& image, cv::Mat& anomalyMap, float score, float threshold = 0.5);
    };
}

#endif
