use anchor_lang::prelude::*;

declare_id!("Ayn4pDdoAHmoaRD2edRFxdpsMsmg3faU7rChLHDTaL3T");

#[program]
pub mod reputation_registry {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let deployment_authorized = false;
        require!(deployment_authorized, ReputationError::BootstrapDisabled);
        let state = &mut ctx.accounts.reputation_state;
        state.authority = ctx.accounts.authority.key();
        state.total_agents = 0;
        state.created_at = Clock::get()?.unix_timestamp;
        Ok(())
    }

    pub fn register_agent(ctx: Context<RegisterAgent>) -> Result<()> {
        let state = &mut ctx.accounts.reputation_state;
        let rep = &mut ctx.accounts.reputation;

        rep.agent = ctx.accounts.agent.key();
        rep.score = 0;
        rep.tier = ReputationTier::Unverified;
        rep.last_updated = Clock::get()?.unix_timestamp;

        state.total_agents = state
            .total_agents
            .checked_add(1)
            .ok_or(ReputationError::ArithmeticOverflow)?;

        emit!(AgentReputationRegistered {
            agent: rep.agent,
            registered_at: rep.last_updated,
        });
        Ok(())
    }

    pub fn update_reputation(ctx: Context<UpdateReputation>, score: u8) -> Result<()> {
        require!(score <= 100, ReputationError::ScoreOutOfRange);

        let rep = &mut ctx.accounts.reputation;
        rep.score = score;
        rep.tier = match score {
            0..=19 => ReputationTier::Unverified,
            20..=39 => ReputationTier::Bronze,
            40..=59 => ReputationTier::Silver,
            60..=79 => ReputationTier::Gold,
            80..=100 => ReputationTier::Platinum,
            _ => ReputationTier::Unverified,
        };
        rep.last_updated = Clock::get()?.unix_timestamp;

        emit!(ReputationUpdated {
            agent: rep.agent,
            score,
            tier: rep.tier,
            updated_at: rep.last_updated,
        });
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        payer = authority,
        space = 8 + 32 + 8 + 8,
        seeds = [b"reputation"],
        bump
    )]
    pub reputation_state: Account<'info, ReputationState>,
    #[account(mut)]
    pub authority: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct RegisterAgent<'info> {
    #[account(
        mut,
        seeds = [b"reputation"],
        bump
    )]
    pub reputation_state: Account<'info, ReputationState>,
    #[account(
        init,
        payer = agent,
        space = 8 + 32 + 1 + 1 + 8,
        seeds = [b"rep", agent.key().as_ref()],
        bump
    )]
    pub reputation: Account<'info, AgentReputation>,
    #[account(mut)]
    pub agent: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct UpdateReputation<'info> {
    #[account(
        seeds = [b"reputation"],
        bump,
        has_one = authority
    )]
    pub reputation_state: Account<'info, ReputationState>,
    #[account(mut)]
    pub reputation: Account<'info, AgentReputation>,
    pub authority: Signer<'info>,
}

#[account]
pub struct ReputationState {
    pub authority: Pubkey,
    pub total_agents: u64,
    pub created_at: i64,
}

#[account]
pub struct AgentReputation {
    pub agent: Pubkey,
    pub score: u8,
    pub tier: ReputationTier,
    pub last_updated: i64,
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, PartialEq, Eq)]
pub enum ReputationTier {
    Unverified,
    Bronze,
    Silver,
    Gold,
    Platinum,
}

#[event]
pub struct AgentReputationRegistered {
    pub agent: Pubkey,
    pub registered_at: i64,
}

#[event]
pub struct ReputationUpdated {
    pub agent: Pubkey,
    pub score: u8,
    pub tier: ReputationTier,
    pub updated_at: i64,
}

#[error_code]
pub enum ReputationError {
    #[msg("Score must be between 0 and 100")]
    ScoreOutOfRange,
    #[msg("Arithmetic overflow")]
    ArithmeticOverflow,
    #[msg("Bootstrap is disabled until a source-backed partner authority design is approved")]
    BootstrapDisabled,
}
