#pragma once
#include <windows.h>
#include <vector>
#include <string>
#include <map>
#include "../include/hwscapture.h"

class CaptureManager
{
public:
    struct Slot
    {
        int index = 0;
        HWND hwnd = NULL;
        bool active = false;
        bool selected = false;
        bool useOsd = false;
        bool useCrop = false;
        bool recording = false;
        bool audioMonitorEnabled = false;
        bool dateTimeOsd = false;
        int dateTimeOsdId = 10000;
        HWS_VIDEO_INPUT_CONFIG config = {};
        HWS_VIDEO_CROP_RECT cropRect = {};
        HWS_PORT videoIn = NULL;
        HWS_PORT render = NULL;
        HWS_PORT crop = NULL;
        HWS_PORT osd = NULL;
        HWS_PORT audioIn = NULL;
        HWS_PORT recorder = NULL;
        wchar_t recordPath[MAX_PATH] = {};
        wchar_t snapshotDir[MAX_PATH] = {};
        HWS_IMAGE_FORMAT snapshotFormat = HWS_IMAGE_FORMAT_BMP;
        std::vector<int> osdIds;
        std::vector<HWS_OSD_ITEM> osdItems;
    };

    bool Initialize();
    void Shutdown();
    void SetSlotWindows(const std::vector<HWND>& hwnds);
    int SlotCount() const;
    Slot* GetSlot(int index);
    void SelectSlot(int index);
    int SelectedSlot() const { return m_selectedSlot; }

    bool AddVideoSource(HWND owner, int slotIndex, const HWS_VIDEO_INPUT_CONFIG& cfg);
    bool AddDefaultVideoSource(HWND owner, int slotIndex);
    bool AddAudioSource(HWND owner, int slotIndex, int deviceIndex);
    void StopSlot(int slotIndex);
    void StopSlotAndRepairPeers(int slotIndex);
    void StopAll();

    bool StartRecorder(HWND owner, int slotIndex);
    void StopRecorder(int slotIndex);
    bool CaptureSnapshot(HWND owner, int slotIndex);
    void ConfigureSnapshot(HWND owner, int slotIndex);

    bool AddTextOsd(int slotIndex, const wchar_t* text);
    bool AddOsdItem(int slotIndex, HWS_OSD_ITEM item);
    bool AddDateTimeOsd(int slotIndex);
    bool AddImageOsd(HWND owner, int slotIndex);
    void UpdateDateTimeOsd();
    void RemoveLastOsd(int slotIndex);
    void ClearOsd(int slotIndex);

    bool SetCrop(int slotIndex, const HWS_VIDEO_CROP_RECT& rc);
    void RemoveCrop(int slotIndex);

    bool EnableAudioMonitor(int slotIndex);
    void DisableAudioMonitor(int slotIndex);

    bool RecorderVideoCallbackEnabled() const { return m_recVideoCb; }
    bool RecorderAudioCallbackEnabled() const { return m_recAudioCb; }
    void ToggleRecorderVideoCallback() { m_recVideoCb = !m_recVideoCb; }
    void ToggleRecorderAudioCallback() { m_recAudioCb = !m_recAudioCb; }

private:
    bool RebuildVideoChain(HWND owner, int slotIndex);
    bool RebuildVideoChainInternal(HWND owner, int slotIndex, bool repairPeers);
    void DestroyVideoChain(Slot& s);
    int FindVideoSourceOwnerSlot(int deviceIndex) const;
    void RebuildVideoSourceOwnerMap();
    struct PeerRestartInfo { int index; HWS_VIDEO_INPUT_CONFIG config; };
    std::vector<PeerRestartInfo> CollectSameDevicePeers(int sourceSlotIndex, int deviceIndex) const;
    void EnsureOsd(Slot& s);
    std::wstring MakeSnapshotFileName(int slotIndex, HWS_IMAGE_FORMAT fmt) const;
    std::vector<Slot> m_slots;
    int m_selectedSlot = 0;
    bool m_initialized = false;
    bool m_recVideoCb = false;
    bool m_recAudioCb = false;
    HWS_PORT m_audioMonitorMux = NULL;
    HWS_PORT m_audioMonitorRender = NULL;
    int m_audioMonitorCount = 0;
    std::map<int, int> m_videoSourceOwnerSlotByDevice;
};

std::wstring HwsUtf8ToWide(const char* text);
const wchar_t* HwsPixelFormatText(HWS_PIXEL_FORMAT fmt);
