#pragma once

#include <Arduino.h>
#include <SD.h>
#include "Config.h"
#include "GnssTypes.h"

namespace field_qa {

class StorageManager {
 public:
  bool startLog(const char* runId, const char* bootTimestampUtc);
  bool mounted() const;
  bool ready() const;
  const char* currentPath() const;
  const char* lastError() const;
  bool fileOpen() const;
  size_t bufferedBytes() const;
  size_t logFileCount() const;
  bool appendSampleCsv(const GnssSample& sample,
                       uint32_t sampleSeq,
                       uint32_t msSinceRunStart,
                       const char* runId,
                       const char* bootTimestampUtc);
  bool appendSatelliteCsv(const GnssSample& sample,
                          uint32_t sampleSeq,
                          uint32_t msSinceRunStart,
                          const SatelliteInfo* satellites,
                          size_t satelliteCount,
                          const char* runId,
                          const char* bootTimestampUtc);
  bool flush();
  void close();
  void listFiles(Stream& out);
  void catFile(Stream& out, const char* path);
  void eraseCsv(Stream& out);
  void eraseLogs(Stream& out);
  bool eraseFile(const char* path);
  bool normalizePath(const char* input, String& normalized) const;

 private:
  bool ensureDir();
  bool openFile();
  bool reopenFileForAppend();
  void writeHeader(const char* runId, const char* bootTimestampUtc);
  String makeFilePath(const char* runId) const;
  bool appendLine(const String& line);
  bool appendBytes(const char* data, size_t len);
  bool writePendingBuffer();
  bool writeFully(const uint8_t* data, size_t len, const char* context);
  size_t countLogsRecursive(const char* path) const;
  void listFilesRecursive(File& dir, Stream& out);
  void eraseCsvRecursive(File& dir, const char* parentPath);

  bool m_ready = false;
  bool m_newFile = false;
  String m_path;
  String m_lastError;
  File m_file;
  char m_buffers[2][kStorageBufferBytes] = {};
  size_t m_bufferLengths[2] = {0, 0};
  bool m_bufferPending[2] = {false, false};
  uint8_t m_activeBuffer = 0;
};

}  // namespace field_qa
