-- =========================================================
-- Cooperativa Agricola - Coop State
-- =========================================================
-- Mantém o estado central da cooperativa:
--   - Quem é o dono (ownerFarmId)
--   - Constraint de instância única (só 1 cooperativa por mapa)
--   - Helpers de spread/preço
--
-- ATENÇÃO: este arquivo deve ser source-d ANTES de DepotSystem.lua
-- no main.lua.
-- =========================================================

---@class CoopState
CoopState = {}
local CoopState_mt = Class(CoopState)

-- Constantes de spread (configuráveis em DepotSettings)
CoopState.DEFAULT_SELL_SPREAD = 0.10   -- 10% de desconto pra quem vende à coop
CoopState.DEFAULT_BUY_SPREAD  = 0.20   -- 20% de markup pra quem compra da coop

-- Sentinela: nenhum dono ainda definido
CoopState.NO_OWNER = 0

function CoopState.new()
    local self = setmetatable({}, CoopState_mt)
    self.ownerFarmId  = CoopState.NO_OWNER
    self.depotCount   = 0   -- quantos depots foram registrados (target: máx 1)
    return self
end

-- ─── Owner ────────────────────────────────────────────────

function CoopState:hasOwner()
    return self.ownerFarmId and self.ownerFarmId ~= CoopState.NO_OWNER
end

function CoopState:setOwner(farmId)
    if not farmId or farmId == 0 then return false end
    if self:hasOwner() then
        DepotLogger.info("CoopState: owner already set to farmId=%d (ignored attempt to set to %d)",
            self.ownerFarmId, farmId)
        return false
    end
    self.ownerFarmId = farmId
    DepotLogger.info("CoopState: owner set to farmId=%d", farmId)
    return true
end

function CoopState:isOwner(farmId)
    if not self:hasOwner() then return false end
    -- Comparação numérica robusta (evita "1" == 1 dar false)
    local owner = tonumber(self.ownerFarmId)
    local who   = tonumber(farmId)
    if not owner or not who then return false end
    return owner == who
end

function CoopState:clearOwner()
    -- Chamado quando o último depot é removido
    DepotLogger.info("CoopState: owner cleared (was farmId=%d)", self.ownerFarmId or 0)
    self.ownerFarmId = CoopState.NO_OWNER
end

-- ─── Single-instance constraint ───────────────────────────

function CoopState:canRegisterNewDepot()
    return self.depotCount < 1
end

function CoopState:onDepotRegistered()
    self.depotCount = self.depotCount + 1
end

function CoopState:onDepotUnregistered()
    self.depotCount = math.max(0, self.depotCount - 1)
    if self.depotCount == 0 then
        self:clearOwner()
    end
end

-- ─── Preço com spreads ────────────────────────────────────
-- Retorna o preço efetivo que o jogador vai sentir, baseado em:
--   - sua relação com a cooperativa (dono ou outro)
--   - direção da operação (compra ou venda)
--
-- marketPrice = preço base do FS25 (pricePerLiter do fillType)

function CoopState:getSellSpread()
    local settings = g_DepotManager and g_DepotManager.settings
    return (settings and settings.coopSellSpread) or CoopState.DEFAULT_SELL_SPREAD
end

function CoopState:getBuySpread()
    local settings = g_DepotManager and g_DepotManager.settings
    return (settings and settings.coopBuySpread) or CoopState.DEFAULT_BUY_SPREAD
end

-- Preço que o jogador RECEBE ao vender à coop (litro)
-- Decisão de projeto: dono também vende ao mesmo preço (ele tá movendo
-- estoque interno; o spread só faz sentido pros outros).
function CoopState:getSellPricePerLiter(marketPrice, sellerFarmId)
    if self:isOwner(sellerFarmId) then
        -- Dono vendendo ao próprio estoque: simplesmente move material
        -- (mecanicamente vira "depositar" e zera money flow, mas pra ficar
        -- consistente com o sistema atual de revenue, retorna 0)
        return 0
    end
    return marketPrice * (1.0 - self:getSellSpread())
end

-- Preço que o jogador PAGA ao comprar da coop (litro)
-- Dono compra ao preço de mercado puro (vantagem do dono).
function CoopState:getBuyPricePerLiter(marketPrice, buyerFarmId)
    if self:isOwner(buyerFarmId) then
        return marketPrice
    end
    return marketPrice * (1.0 + self:getBuySpread())
end

-- ─── Stream sync (multiplayer) ────────────────────────────

function CoopState:writeStream(streamId)
    streamWriteUInt8(streamId, self.ownerFarmId or 0)
end

function CoopState:readStream(streamId)
    self.ownerFarmId = streamReadUInt8(streamId)
end

-- ─── Save / Load ──────────────────────────────────────────

function CoopState:saveToXML(xmlFile, key)
    xmlFile:setInt(key .. "#ownerFarmId", self.ownerFarmId or 0)
end

function CoopState:loadFromXML(xmlFile, key)
    self.ownerFarmId = xmlFile:getInt(key .. "#ownerFarmId", 0)
end
