#pragma once

#include <maps/wikimap/mapspro/services/mrc/eye/lib/common/include/base_worker.h>
#include <maps/wikimap/mapspro/services/mrc/eye/lib/common/include/config.h>

#include <maps/wikimap/mapspro/services/mrc/libs/common/include/pg_locks.h>

#include <maps/wikimap/mapspro/services/mrc/libs/db/include/common.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/eye_panorama.h>

#include <pqxx/pqxx>

#include <map>
#include <optional>
#include <string>

namespace maps::mrc::eye {

struct ImportPanoramaFrameConfig {
    MrcWorkerConfig mrc;
};

inline bool isValid(const ImportPanoramaFrameConfig& config)
{
    return isValid(config.mrc);
}

// This class makes Eye frames out of panoramas. It cuts out (reprojects) six
// FHD frames on a circle with seventy degrees horizontal FOV. Thus each
// panorama has two overlapping regions of ten degrees with two panoramas next
// to it.
//
// The source panoramas are loaded from sources.eye_panorama and a couple of
// specific panorama frame tables are filled in.
//
// The first one is eye::panorama_to_frame which holds relations of original
// panorama and its derivative framse (six per each panorama). Additionaly it
// contains specific panorama frame data such as its heading, tilt, horizontal
// FOV, and size.
//
// The second one is panorama_session_to_device which holds relations from
// pair <session ID, deviation> to device. This deviation is CW rotation
// around panorama coordinate system centre with sixty degrees stride.
//
// Each pair <session ID, deviation> is assigned its own device so panorama
// frames with the same orientation can be gathered together in a sequence for
// those algorithms which require them to be sequenced.
//
// Also there are Eye tables this class fills in. Namely eye.frame,
// eye.device, eye.frame_to_device, eye.frame_location. These are later used
// by Eye for data mining and hypotesis posting.
//
// The class implements common worker Eye interface.
class ImportPanoramaFrame :
    public BaseWorkerWithConfig<
        ImportPanoramaFrameConfig,
        common::LockId::EyeImportPanoramaFrame,
        db::PanoramaOID> {
public:
    using BaseWorkerWithConfig::BaseWorkerWithConfig;

    void processBatch(const db::PanoramaOIDs& oids) override;

    // Sets to metadaa last transaction ID, panorama session ID, order num,
    // and import time.
    bool processBatchInLoopMode(std::size_t size) override;
};

} // namespace maps::mrc::eye
