#ifndef SDATABASE_H
#define SDATABASE_H

#include <QObject>

#include <QMutex>

//#include "sqlite3.h"

#include "acquisition_info.h"

#include "common.h"

namespace SUTIL
{
    class SDatabase : public QObject
    {
        Q_OBJECT
    public:
        explicit SDatabase(const QString& connectionName, QObject *parent = nullptr);
        virtual ~SDatabase();

        // 트랜잭션 함수 이름 명확화
        bool BeginTransaction();
        bool Commit();
        bool Rollback();

        int OpenDatabase(QString strFilename);
        void CloseDatabase();

        static void DeleteListReponse(QList<QStringList*>& listResponse);


        // ExecuteQuery와 Execute를 하나로 통합하고 파라미터 바인딩을 지원하도록 개선
        bool ExecuteQuery(const QString& strQuery, QList<QStringList*>& resultList);
        bool ExecuteNonQuery(const QString& strQuery);
        // SQL Injection 방지를 위한 파라미터 바인딩 버전 (강력 추천)
        bool ExecuteQuery(const QString& strQuery, const QVariantList& params, QList<QStringList*>& resultList);
        bool ExecuteNonQuery(const QString& strQuery, const QVariantList& params);

        void MakeTableDataInfo();

        void MakeViewTable();

        void MakeTableUser();
        void MakeTableAdvancedSetting();
        void MakeTableReserved();

        void MakeAcquisitionTempTable();

        void AddAcquisitionTempToImage();
        void ClearAcquisitionTempTable();

        bool AddImageToAcquisitionTemp(int nStudyIndex);

        void CheckAdavancedTable();
        void CheckLoginTable();

        QString GetValueAdavancedTable(const QString& strColumn);

        //void Clear();

        //bool IsExecute();

        bool AutoremoveImageTable();

        QList<QStringList> QueryWorklistTableHeader();
        QList<QStringList> QueryWorklistTableHeaderVisible();
        QList<QStringList> QueryWorklistTableHeaderInvisible();
        QList<QStringList> QueryHistoryTableHeader();
        QList<QStringList> QueryHistoryTableHeaderVisible();
        QList<QStringList> QueryHistoryTableHeaderInvisible();

        int InsertPatient(ACQUISITION_INFO* pAcquisitionInfo);

        int InsertStudy(ACQUISITION_INFO* pAcquisitionInfo);



        int InsertSeriesImage(ACQUISITION_INFO* pAcquisitionInfo);
        int InsertSeriesMovie(ACQUISITION_INFO* pAcquisitionInfo);


        int InsertImage(ACQUISITION_INFO* pAcquisitionInfo);
        int InsertVideo(ACQUISITION_INFO* pAcquisitionInfo);

        int UpdateImage(ACQUISITION_INFO* pAcquisitionInfo, const vector<CAPTURE_IMAGE*>& listCaptureImage);
        int UpdateImageOnAcquistionTemp(ACQUISITION_INFO* pAcquisitionInfo, const vector<CAPTURE_IMAGE*>& listCaptureImage);

        int GetHistory(SEARCH_ITEM* pSearchItem);

        QList<QStringList> GetHistoryStudy(SEARCH_ITEM* pSearchItem, bool bWithDelete=false);

        QList<QStringList> GetImageWithStudyIndex(int nIndex);
        QList<QStringList> GetImageWithStudyIndexASC(int nIndex);

        bool ImageDeleteFromImage(const QString& strFile, bool bDelete);
        bool ImageDeleteFromAcqusitionTemp(const QString& strFile, bool bDelete);

        bool ImageDeleteFromImageInstanceUID(const QString& strInstanceUID, bool bDelete);

        int GetAcquisitionNumber(const QString& strFile);

        int GetSeriesImageIndexWithInstanceUID(const QString& strStudyInstanceUID);
        int GetSeriesVideoIndexWithInstanceUID(const QString& strStudyInstanceUID);

        vector<QString> GetImageListWithStudy(const QString& strStudyDate, const QString& strPatientID);
        vector<QString> GetImageListWithStudyIndex(const QString& strStudyIndex);

        vector<QString> GetVideoListWithStudy(const QString& strStudyDate, const QString& strPatientID);
        vector<QString> GetVideoListWithStudyIndex(const QString& strStudyIndex);

        void SendUpdate(const QString& strFilename);

        void SendUpdateAcquisitionTemp(const QString& strFilename);


        int GetImageMaxAcquisitionNumber(const QString& strSeriesIndex);
        int GetVideoMaxAcquisitionNumber(const QString& strSeriesIndex);


        //QList<QStringList*>* GetResult();

        QList<QStringList> GetScheduledDeleteFileList();


        QStringList GetScheduledDeleteStudyDateList();

        void UpdateScheduledDeleteCompleteStudyDate();

        bool SetDeleteStorageFile(const QString& strFile);

        QStringList GetVideoFileList();

        int GetStudyIndexWithStudyInstanceUID(const QString& strStudyInstanceUID);


        vector<QString> GetSendList(int nStudyIndex);


        QList<QStringList> GetExitSendListInfo(int nStudyIndex);

        vector<QString> GetSendListAcquisitionTemp(int nStudyIndex);

        bool CacheWrite();

        QString connectionName();

        vector<QString> GetAllFilesForStudyIndex(int studyIndex);


    signals:

    public slots:

    public:
        int getOrInsertSeries(ACQUISITION_INFO *pAcquisitionInfo, int seriesNumber);
        int upsertImages(const QString& tableName, ACQUISITION_INFO* pAcquisitionInfo, const vector<CAPTURE_IMAGE*>& listCaptureImage);
        QVariant executeScalar(const QString& query, const QVariantList& params = QVariantList());

        int getSeriesIndex(const QString& studyInstanceUID, int seriesNumber);

        bool updateSendStatus(const QString& tableName, const QString& filename);

        bool IsExecute();

    protected:
        // --- 변경된 멤버 변수 ---
        QString m_connectionName; // 각 인스턴스의 고유 DB 커넥션 이름
        bool m_bExecute;

        static uint64_t m_nUsage;

        // QMutex m_Lock; // 불필요
        // sqlite3* m_pSqliteDB; // 불필요
        // QList<QStringList*>* m_pResult; // 불필요, 함수 인자로 처리
    };
}


#endif // SDATABASE_H

