# frozen_string_literal: true

module SynorStorage
  # Network environment
  module Network
    MAINNET = "mainnet"
    TESTNET = "testnet"
    DEVNET = "devnet"
  end

  # Pin status
  module PinStatus
    QUEUED = "queued"
    PINNING = "pinning"
    PINNED = "pinned"
    FAILED = "failed"
  end

  # Configuration
  class Config
    attr_reader :api_key, :base_url, :gateway, :network, :timeout, :retries, :debug

    def initialize(
      api_key:,
      base_url: "https://storage.synor.io/v1",
      gateway: "https://gateway.synor.io",
      network: Network::MAINNET,
      timeout: 300,
      retries: 3,
      debug: false
    )
      @api_key = api_key
      @base_url = base_url
      @gateway = gateway
      @network = network
      @timeout = timeout
      @retries = retries
      @debug = debug
    end
  end

  # Upload options
  class UploadOptions
    attr_reader :name, :content_type, :pin, :metadata, :wrap_with_directory

    def initialize(
      name: nil,
      content_type: nil,
      pin: true,
      metadata: nil,
      wrap_with_directory: false
    )
      @name = name
      @content_type = content_type
      @pin = pin
      @metadata = metadata
      @wrap_with_directory = wrap_with_directory
    end
  end

  # Upload response
  class UploadResponse
    attr_reader :cid, :size, :name, :pinned

    def initialize(cid:, size:, name: nil, pinned: true)
      @cid = cid
      @size = size
      @name = name
      @pinned = pinned
    end

    def self.from_hash(h)
      new(
        cid: h["cid"],
        size: h["size"],
        name: h["name"],
        pinned: h["pinned"] || true
      )
    end
  end

  # Pin request
  class PinRequest
    attr_reader :cid, :name, :metadata, :origins

    def initialize(cid:, name: nil, metadata: nil, origins: nil)
      @cid = cid
      @name = name
      @metadata = metadata
      @origins = origins
    end

    def to_h
      {
        cid: @cid,
        name: @name,
        metadata: @metadata,
        origins: @origins
      }.compact
    end
  end

  # Pin information
  class Pin
    attr_reader :cid, :name, :status, :size, :created_at, :metadata

    def initialize(cid:, name:, status:, size:, created_at:, metadata: nil)
      @cid = cid
      @name = name
      @status = status
      @size = size
      @created_at = created_at
      @metadata = metadata
    end

    def self.from_hash(h)
      new(
        cid: h["cid"],
        name: h["name"],
        status: h["status"],
        size: h["size"],
        created_at: h["created_at"],
        metadata: h["metadata"]
      )
    end
  end

  # File entry for directory operations
  class FileEntry
    attr_reader :path, :content, :content_type

    def initialize(path:, content:, content_type: nil)
      @path = path
      @content = content
      @content_type = content_type
    end
  end

  # Directory entry
  class DirectoryEntry
    attr_reader :name, :cid, :size, :type

    def initialize(name:, cid:, size:, type:)
      @name = name
      @cid = cid
      @size = size
      @type = type
    end

    def self.from_hash(h)
      new(
        name: h["name"],
        cid: h["cid"],
        size: h["size"],
        type: h["type"]
      )
    end

    def file?
      @type == "file"
    end

    def directory?
      @type == "directory"
    end
  end

  # CAR file
  class CarFile
    attr_reader :root_cid, :data, :size

    def initialize(root_cid:, data:, size:)
      @root_cid = root_cid
      @data = data
      @size = size
    end

    def self.from_hash(h)
      new(
        root_cid: h["root_cid"],
        data: h["data"],
        size: h["size"]
      )
    end
  end

  # Storage statistics
  class StorageStats
    attr_reader :total_size, :pin_count, :bandwidth_used, :storage_limit, :bandwidth_limit

    def initialize(total_size:, pin_count:, bandwidth_used:, storage_limit:, bandwidth_limit:)
      @total_size = total_size
      @pin_count = pin_count
      @bandwidth_used = bandwidth_used
      @storage_limit = storage_limit
      @bandwidth_limit = bandwidth_limit
    end

    def self.from_hash(h)
      new(
        total_size: h["total_size"],
        pin_count: h["pin_count"],
        bandwidth_used: h["bandwidth_used"],
        storage_limit: h["storage_limit"],
        bandwidth_limit: h["bandwidth_limit"]
      )
    end
  end
end
