use serde::{Deserialize, Serialize};
use steel::*;

use crate::state::governance_pda;
use super::GovernanceAccount;

/// Singleton governance configuration account
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
pub struct Governance {
    /// Admin address (only admin can create proposals)
    pub admin: Pubkey,
    
    /// Total staked score (for quorum calculation)
    /// This should be updated when proposals are created to snapshot the total stake score
    /// Voting power is based on stake score (balance * multiplier) from OIL program
    pub total_staked_score: u64,
    
    /// Total number of proposals created
    pub proposal_count: u64,
    
    /// Voting period duration in seconds (default: 7 days)
    pub voting_period_seconds: u64,
    
    /// Buffer field (formerly timelock_seconds, not used)
    pub buffer_d: u64,
    
    /// Quorum percentage in basis points (default: 5% = 500 bps)
    /// Quorum is calculated as: (total_staked_score * quorum_percentage_bps) / 10_000
    pub quorum_percentage_bps: u64,
    
    /// Threshold for proposals in basis points (default: 50% = 5000 bps)
    /// Single threshold for all proposals (simplified from tier system)
    pub threshold_bps: u64,
    
    /// Minimum stake duration in seconds before voting power is granted (default: 7 days = 604800 seconds)
    pub min_stake_duration_seconds: u64,
    
    /// Address of the OIL program (for cross-program invocations to read Pool and Stake accounts)
    pub oil_program_id: Pubkey,
    
    /// Address of the OIL mint
    pub oil_mint: Pubkey,
    
    /// Buffer fields for future use
    pub buffer_a: u64,
    pub buffer_b: u64,
    pub buffer_c: u64,
    /// Executor address (can finalize proposals after voting ends)
    /// Added via migration - account extended from 184 to 216 bytes
    pub executor: Pubkey,
}

impl Governance {
    pub fn pda() -> (Pubkey, u8) {
        governance_pda()
    }
    
    /// Calculate quorum threshold based on total staked score
    pub fn quorum_threshold(&self) -> u64 {
        (self.total_staked_score * self.quorum_percentage_bps) / 10_000
    }
    
    /// Get threshold for proposals (single threshold for all proposals)
    pub fn threshold(&self) -> u64 {
        self.threshold_bps
    }
}

account!(GovernanceAccount, Governance);
