//! `SeaORM` Entity for patch proposals (merge requests)

use sea_orm::entity::prelude::*;
use serde::Serialize;

/// Status of a patch proposal
#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, Serialize)]
#[sea_orm(rs_type = "String", db_type = "String(StringLen::N(16))")]
pub enum Status {
    /// Draft - not yet ready for review
    #[sea_orm(string_value = "draft")]
    Draft,
    /// Open - ready for review
    #[sea_orm(string_value = "open")]
    Open,
    /// Closed - withdrawn or rejected
    #[sea_orm(string_value = "closed")]
    Closed,
    /// Merged - successfully integrated
    #[sea_orm(string_value = "merged")]
    Merged,
}

/// Merge policy for a patch proposal
#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, Serialize)]
#[sea_orm(rs_type = "String", db_type = "String(StringLen::N(32))")]
pub enum MergePolicy {
    /// Prefer fast-forward, fall back to merge commit
    #[sea_orm(string_value = "prefer-fast-forward")]
    PreferFastForward,
    /// Only allow fast-forward merges
    #[sea_orm(string_value = "fast-forward-only")]
    FastForwardOnly,
    /// Always create a merge commit
    #[sea_orm(string_value = "merge-commit-only")]
    MergeCommitOnly,
    /// Rebase then fast-forward
    #[sea_orm(string_value = "rebase-then-fast-forward")]
    RebaseThenFastForward,
}

#[sea_orm::model]
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize)]
#[sea_orm(table_name = "patch_proposals")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i64,
    #[sea_orm(unique)]
    pub uuid: Uuid,
    pub repository_id: i64,
    /// Local user who created this patch proposal (null for remote-created proposals).
    pub creator_id: Option<i64>,
    /// Remote actor who created this patch proposal (for federated proposals).
    /// Exactly one of creator_id or remote_actor_id is set.
    pub remote_actor_id: Option<i64>,
    /// The inbound Offer activity id, for idempotency on federation.
    pub remote_offer_id: Option<String>,
    /// The activity URL of the last emitted/accepted Resolve, for Undo(Resolve) correlation.
    pub resolve_activity_url: Option<String>,
    pub number: i64,
    pub summary: String,
    pub description: Option<String>,
    pub source_ref: String,
    pub target_branch: String,
    pub status: Status,
    pub merge_policy: MergePolicy,
    /// A jj change-id parsed from the head commit's raw headers, if one is
    /// present. This survives jj rewrites, so pushes of the same logical
    /// change route to the same patch proposal instead of creating a new one.
    pub change_id: Option<String>,
    pub created_at: DateTimeWithTimeZone,
    pub updated_at: DateTimeWithTimeZone,
    #[sea_orm(
        belongs_to,
        from = "repository_id",
        to = "id",
        on_update = "NoAction",
        on_delete = "Cascade"
    )]
    pub repositories: BelongsTo<super::repositories::Entity>,
}

impl ActiveModelBehavior for ActiveModel {}
