using Dapper;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OFACScraper.Configuration;

namespace OFACScraper;

/// <summary>
/// SQLite-backed store tracking which OFAC records have been processed and synced to S3.
/// </summary>
public class CheckpointStore : IDisposable
{
    private readonly SqliteConnection _db;
    private readonly ILogger<CheckpointStore> _logger;

    public CheckpointStore(IOptions<StorageOptions> options, ILogger<CheckpointStore> logger)
    {
        _logger = logger;
        var dbPath = options.Value.DatabasePath;
        Directory.CreateDirectory(Path.GetDirectoryName(dbPath)!);
        _db = new SqliteConnection($"Data Source={dbPath}");
        _db.Open();
        InitSchema();
    }

    public void Dispose() => _db.Dispose();

    private void InitSchema()
    {
        _db.Execute("""
            CREATE TABLE IF NOT EXISTS records (
                text_id      TEXT PRIMARY KEY,
                date         TEXT NOT NULL,
                name         TEXT NOT NULL,
                penalty_usd  REAL,
                document_url TEXT NOT NULL,
                file_name    TEXT NOT NULL,
                year         INTEGER NOT NULL,
                processed_at TEXT NOT NULL,
                s3_synced    INTEGER NOT NULL DEFAULT 0
            )
            """);
    }

    public bool HasRecord(string textId) =>
        _db.ExecuteScalar<int>("SELECT COUNT(1) FROM records WHERE text_id = @textId", new { textId }) > 0;

    public void MarkProcessed(string textId, DateTime date, string name, decimal? penaltyUsd,
        string documentUrl, string fileName, int year)
    {
        _db.Execute("""
            INSERT OR REPLACE INTO records (text_id, date, name, penalty_usd, document_url, file_name, year, processed_at, s3_synced)
            VALUES (@textId, @date, @name, @penaltyUsd, @documentUrl, @fileName, @year, @processedAt, 0)
            """,
            new
            {
                textId,
                date = date.ToString("yyyy-MM-dd"),
                name,
                penaltyUsd,
                documentUrl,
                fileName,
                year,
                processedAt = DateTime.UtcNow.ToString("O")
            });
    }

    public void MarkS3Synced(string textId)
    {
        _db.Execute("UPDATE records SET s3_synced = 1 WHERE text_id = @textId", new { textId });
    }

    public int GetTotalCount() =>
        _db.ExecuteScalar<int>("SELECT COUNT(1) FROM records");

    public int GetYearCount(int year) =>
        _db.ExecuteScalar<int>("SELECT COUNT(1) FROM records WHERE year = @year", new { year });
}
