//! Compliance types and data structures
//!
//! Common types used across GDPR, SOC2, and ISO 27001 compliance modules.

use std::collections::HashMap;

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

// ============================================================================
// GDPR Types
// ============================================================================

/// Personal data export for GDPR Article 15 (Right to Access)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PersonalDataExport {
    /// User identifier
    pub user_id: String,

    /// Export timestamp
    pub exported_at: DateTime<Utc>,

    /// Data categories
    pub data_categories: HashMap<String, serde_json::Value>,

    /// Audit logs related to user
    pub audit_logs: Vec<AuditLogEntry>,

    /// Consent records
    pub consents: Vec<ConsentRecord>,

    /// Export format
    pub format: ExportFormat,
}

/// Deletion report for GDPR Article 17 (Right to Erasure)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeletionReport {
    /// User identifier
    pub user_id: String,

    /// Deletion timestamp
    pub deleted_at: DateTime<Utc>,

    /// Reason for deletion
    pub reason: ErasureReason,

    /// Systems where data was deleted
    pub deleted_from: Vec<String>,

    /// Retention requirements (data kept for legal reasons)
    pub retained_for_legal: Vec<RetentionRequirement>,

    /// Verification hash (proof of deletion)
    pub verification_hash: String,
}

/// Reason for data erasure
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ErasureReason {
    /// User requested deletion (Art. 17(1)(b))
    UserRequest,

    /// Retention period expired
    RetentionExpired,

    /// Consent withdrawn (Art. 17(1)(b))
    ConsentWithdrawn,

    /// No longer necessary (Art. 17(1)(a))
    NoLongerNecessary,

    /// Objection to processing (Art. 17(1)(c))
    ObjectionToProcessing,

    /// Unlawful processing (Art. 17(1)(d))
    UnlawfulProcessing,

    /// Legal obligation (Art. 17(1)(e))
    LegalObligation,
}

/// Export format for data portability
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ExportFormat {
    /// JSON format (machine-readable)
    Json,

    /// CSV format (spreadsheet)
    Csv,

    /// XML format (structured)
    Xml,

    /// PDF format (human-readable)
    Pdf,
}

/// Processing type for objections
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ProcessingType {
    /// Direct marketing
    DirectMarketing,

    /// Profiling
    Profiling,

    /// Automated decision-making
    AutomatedDecisionMaking,

    /// Analytics
    Analytics,

    /// Third-party sharing
    ThirdPartySharing,
}

/// Consent record
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConsentRecord {
    /// Consent ID
    pub id: String,

    /// User ID
    pub user_id: String,

    /// Processing type
    pub processing_type: String,

    /// Consent given timestamp
    pub given_at: DateTime<Utc>,

    /// Consent withdrawn timestamp
    pub withdrawn_at: Option<DateTime<Utc>>,

    /// Is consent still valid
    pub is_active: bool,

    /// Legal basis
    pub legal_basis: LegalBasis,
}

/// Legal basis for data processing
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum LegalBasis {
    /// Consent (Art. 6(1)(a))
    Consent,

    /// Contract (Art. 6(1)(b))
    Contract,

    /// Legal obligation (Art. 6(1)(c))
    LegalObligation,

    /// Vital interests (Art. 6(1)(d))
    VitalInterests,

    /// Public task (Art. 6(1)(e))
    PublicTask,

    /// Legitimate interests (Art. 6(1)(f))
    LegitimateInterests,
}

/// Retention requirement
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RetentionRequirement {
    /// Data type
    pub data_type: String,

    /// Retention period
    pub retention_period: String,

    /// Legal basis for retention
    pub legal_basis: String,

    /// Expiration date
    pub expires_at: DateTime<Utc>,
}

/// Audit log entry (simplified)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditLogEntry {
    pub timestamp: DateTime<Utc>,
    pub action: String,
    pub resource: String,
    pub result: String,
}

// ============================================================================
// SOC2 Types
// ============================================================================

/// SOC2 compliance report
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Soc2Report {
    /// Report ID
    pub id: String,

    /// Generated timestamp
    pub generated_at: DateTime<Utc>,

    /// Reporting period (start)
    pub period_start: DateTime<Utc>,

    /// Reporting period (end)
    pub period_end: DateTime<Utc>,

    /// Trust Service Criteria results
    pub criteria: Vec<CriterionResult>,

    /// Overall compliance status
    pub overall_status: ComplianceStatus,

    /// Auditor notes
    pub notes: Vec<String>,
}

/// Trust Service Criterion result
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CriterionResult {
    /// Criterion code (CC1, CC2, etc.)
    pub code: String,

    /// Criterion name
    pub name: String,

    /// Compliance status
    pub status: ComplianceStatus,

    /// Evidence collected
    pub evidence: Vec<Evidence>,

    /// Issues identified
    pub issues: Vec<Issue>,

    /// Remediation actions
    pub remediations: Vec<RemediationAction>,
}

/// Compliance status
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ComplianceStatus {
    /// Fully compliant
    Compliant,

    /// Partially compliant (issues identified)
    PartiallyCompliant,

    /// Not compliant
    NonCompliant,

    /// Not evaluated
    NotEvaluated,
}

/// Evidence for compliance
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Evidence {
    /// Evidence ID
    pub id: String,

    /// Evidence type
    pub evidence_type: EvidenceType,

    /// Description
    pub description: String,

    /// Reference (file path, URL, etc.)
    pub reference: String,

    /// Collection timestamp
    pub collected_at: DateTime<Utc>,

    /// Collector
    pub collected_by: String,
}

/// Evidence type
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum EvidenceType {
    /// Configuration file
    Configuration,

    /// Log file
    LogFile,

    /// Screenshot
    Screenshot,

    /// Policy document
    PolicyDocument,

    /// Audit report
    AuditReport,

    /// Test result
    TestResult,

    /// Certificate
    Certificate,
}

/// Compliance issue
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Issue {
    /// Issue ID
    pub id: String,

    /// Issue severity
    pub severity: IssueSeverity,

    /// Issue description
    pub description: String,

    /// Affected control
    pub control: String,

    /// Identified timestamp
    pub identified_at: DateTime<Utc>,

    /// Resolution status
    pub status: IssueStatus,

    /// Resolution timestamp
    pub resolved_at: Option<DateTime<Utc>>,
}

/// Issue severity
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum IssueSeverity {
    Critical,
    High,
    Medium,
    Low,
    Info,
}

/// Issue resolution status
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum IssueStatus {
    Open,
    InProgress,
    Resolved,
    Accepted,
    Closed,
}

/// Remediation action
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RemediationAction {
    /// Action ID
    pub id: String,

    /// Action description
    pub description: String,

    /// Assigned to
    pub assigned_to: String,

    /// Due date
    pub due_date: DateTime<Utc>,

    /// Status
    pub status: RemediationStatus,

    /// Completion timestamp
    pub completed_at: Option<DateTime<Utc>>,
}

/// Remediation status
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RemediationStatus {
    Pending,
    InProgress,
    Completed,
    Verified,
    Failed,
}

// ============================================================================
// ISO 27001 Types
// ============================================================================

/// ISO 27001 compliance report
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Iso27001Report {
    /// Report ID
    pub id: String,

    /// Generated timestamp
    pub generated_at: DateTime<Utc>,

    /// Annex A control results
    pub controls: Vec<ControlResult>,

    /// Overall compliance status
    pub overall_status: ComplianceStatus,

    /// Risk assessment
    pub risk_assessment: RiskAssessment,
}

/// Control result
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ControlResult {
    /// Control code (A.5, A.6, etc.)
    pub code: String,

    /// Control name
    pub name: String,

    /// Implementation status
    pub status: ImplementationStatus,

    /// Evidence
    pub evidence: Vec<Evidence>,

    /// Issues
    pub issues: Vec<Issue>,
}

/// Implementation status
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ImplementationStatus {
    /// Fully implemented
    Implemented,

    /// Partially implemented
    PartiallyImplemented,

    /// Not implemented
    NotImplemented,

    /// Not applicable
    NotApplicable,
}

/// Risk assessment
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RiskAssessment {
    /// Assessment ID
    pub id: String,

    /// Assessment date
    pub assessed_at: DateTime<Utc>,

    /// Identified risks
    pub risks: Vec<Risk>,

    /// Risk matrix
    pub risk_matrix: HashMap<String, RiskLevel>,
}

/// Risk
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Risk {
    /// Risk ID
    pub id: String,

    /// Risk description
    pub description: String,

    /// Risk category
    pub category: RiskCategory,

    /// Likelihood
    pub likelihood: RiskLevel,

    /// Impact
    pub impact: RiskLevel,

    /// Overall risk level (likelihood × impact)
    pub overall_level: RiskLevel,

    /// Mitigation measures
    pub mitigations: Vec<String>,

    /// Status
    pub status: RiskStatus,
}

/// Risk category
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RiskCategory {
    /// Information security
    InformationSecurity,

    /// Operational
    Operational,

    /// Compliance
    Compliance,

    /// Financial
    Financial,

    /// Reputational
    Reputational,

    /// Strategic
    Strategic,
}

/// Risk level
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RiskLevel {
    VeryLow,
    Low,
    Medium,
    High,
    VeryHigh,
}

/// Risk status
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RiskStatus {
    Identified,
    Assessed,
    Mitigated,
    Accepted,
    Transferred,
    Avoided,
}

// ============================================================================
// Incident Response Types
// ============================================================================

/// Incident response record
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IncidentResponse {
    /// Incident ID
    pub id: String,

    /// Incident severity
    pub severity: IncidentSeverity,

    /// Incident type
    pub incident_type: IncidentType,

    /// Detection timestamp
    pub detected_at: DateTime<Utc>,

    /// Reporting timestamp
    pub reported_at: DateTime<Utc>,

    /// Incident status
    pub status: IncidentStatus,

    /// Affected systems
    pub affected_systems: Vec<String>,

    /// Affected users
    pub affected_users: Vec<String>,

    /// Timeline of events
    pub timeline: Vec<IncidentEvent>,

    /// Remediation steps
    pub remediation: Vec<RemediationStep>,

    /// Containment actions
    pub containment: Vec<String>,

    /// Root cause analysis
    pub root_cause: Option<String>,

    /// Lessons learned
    pub lessons_learned: Vec<String>,
}

/// Incident severity
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum IncidentSeverity {
    /// Critical incident (data breach, system compromise)
    Critical,

    /// High severity (unauthorized access, DoS)
    High,

    /// Medium severity (policy violation)
    Medium,

    /// Low severity (informational)
    Low,
}

/// Incident type
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum IncidentType {
    /// Data breach
    DataBreach,

    /// Unauthorized access
    UnauthorizedAccess,

    /// Malware infection
    MalwareInfection,

    /// Denial of service
    DenialOfService,

    /// Policy violation
    PolicyViolation,

    /// System failure
    SystemFailure,

    /// Insider threat
    InsiderThreat,

    /// Social engineering
    SocialEngineering,

    /// Physical security
    PhysicalSecurity,

    /// Other
    Other,
}

/// Incident status
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum IncidentStatus {
    /// Detected but not confirmed
    Detected,

    /// Confirmed incident
    Confirmed,

    /// Containment in progress
    Containing,

    /// Contained
    Contained,

    /// Eradication in progress
    Eradicating,

    /// Recovery in progress
    Recovering,

    /// Incident resolved
    Resolved,

    /// Post-incident review
    PostIncidentReview,

    /// Closed
    Closed,
}

/// Incident event
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IncidentEvent {
    /// Event timestamp
    pub timestamp: DateTime<Utc>,

    /// Event type
    pub event_type: String,

    /// Event description
    pub description: String,

    /// Event actor
    pub actor: String,
}

/// Remediation step
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RemediationStep {
    /// Step number
    pub step: u32,

    /// Step description
    pub description: String,

    /// Assigned to
    pub assigned_to: String,

    /// Status
    pub status: RemediationStatus,

    /// Completed timestamp
    pub completed_at: Option<DateTime<Utc>>,
}

// ============================================================================
// Data Protection Types
// ============================================================================

/// Data classification
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum DataClassification {
    /// Public data
    Public,

    /// Internal data
    Internal,

    /// Confidential data
    Confidential,

    /// Restricted data (highest protection)
    Restricted,
}

/// Protection report
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProtectionReport {
    /// Report ID
    pub id: String,

    /// Generated timestamp
    pub generated_at: DateTime<Utc>,

    /// Encryption status
    pub encryption: EncryptionStatus,

    /// Access control status
    pub access_control: AccessControlStatus,

    /// Network security status
    pub network_security: NetworkSecurityStatus,
}

/// Encryption status
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EncryptionStatus {
    /// Encryption at rest enabled
    pub at_rest_enabled: bool,

    /// Encryption algorithm
    pub algorithm: String,

    /// Key rotation enabled
    pub key_rotation_enabled: bool,

    /// Last key rotation
    pub last_rotation: Option<DateTime<Utc>>,
}

/// Access control status
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AccessControlStatus {
    /// RBAC enabled
    pub rbac_enabled: bool,

    /// MFA enforced
    pub mfa_enforced: bool,

    /// Session timeout (seconds)
    pub session_timeout: u64,

    /// Password policy enforced
    pub password_policy_enforced: bool,
}

/// Network security status
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkSecurityStatus {
    /// TLS version
    pub tls_version: String,

    /// Certificate valid
    pub certificate_valid: bool,

    /// Certificate expiry
    pub certificate_expires: DateTime<Utc>,

    /// Firewall enabled
    pub firewall_enabled: bool,
}

// ============================================================================
// Combined Reporting
// ============================================================================

/// Combined compliance report
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CombinedReport {
    /// Report ID
    pub id: String,

    /// Generated timestamp
    pub generated_at: DateTime<Utc>,

    /// GDPR report
    pub gdpr: GdprReport,

    /// SOC2 report
    pub soc2: Soc2Report,

    /// ISO 27001 report
    pub iso27001: Iso27001Report,

    /// Overall compliance score (0-100)
    pub compliance_score: u8,
}

/// GDPR report
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GdprReport {
    /// Data processing activities
    pub data_processing_activities: Vec<ProcessingActivity>,

    /// Data retention compliance
    pub data_retention_compliance: RetentionComplianceStatus,

    /// Data subject requests
    pub data_subject_requests: Vec<DataSubjectRequest>,

    /// Data breaches
    pub data_breaches: Vec<DataBreachRecord>,

    /// DPIA assessments
    pub dpia_assessments: Vec<DpiaAssessment>,
}

/// Data processing activity
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProcessingActivity {
    /// Activity name
    pub name: String,

    /// Processing purpose
    pub purpose: String,

    /// Legal basis
    pub legal_basis: LegalBasis,

    /// Data categories
    pub data_categories: Vec<String>,

    /// Data subjects
    pub data_subjects: Vec<String>,

    /// Recipients
    pub recipients: Vec<String>,

    /// Retention period
    pub retention_period: String,
}

/// Retention compliance status
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RetentionComplianceStatus {
    /// Total records
    pub total_records: u64,

    /// Records compliant
    pub compliant_records: u64,

    /// Records requiring action
    pub records_requiring_action: u64,

    /// Compliance percentage
    pub compliance_percentage: f64,
}

/// Data subject request
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataSubjectRequest {
    /// Request ID
    pub id: String,

    /// Request type
    pub request_type: DataSubjectRequestType,

    /// User ID
    pub user_id: String,

    /// Request timestamp
    pub requested_at: DateTime<Utc>,

    /// Completion timestamp
    pub completed_at: Option<DateTime<Utc>>,

    /// Status
    pub status: DataSubjectRequestStatus,
}

/// Data subject request type
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum DataSubjectRequestType {
    Access,
    Rectification,
    Erasure,
    Portability,
    Objection,
    Restriction,
}

/// Data subject request status
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum DataSubjectRequestStatus {
    Received,
    InProgress,
    Completed,
    Rejected,
}

/// Data breach record
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataBreachRecord {
    /// Breach ID
    pub id: String,

    /// Breach timestamp
    pub occurred_at: DateTime<Utc>,

    /// Reported timestamp
    pub reported_at: DateTime<Utc>,

    /// Affected users
    pub affected_users: u64,

    /// Data categories affected
    pub affected_data_categories: Vec<String>,

    /// Notification status
    pub notification_status: BreachNotificationStatus,
}

/// Breach notification status
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum BreachNotificationStatus {
    /// Not yet reported
    NotReported,

    /// Reported to DPA within 72 hours
    ReportedToDpa,

    /// Users notified
    UsersNotified,

    /// Exemption applied
    ExemptionApplied,
}

/// Data Protection Impact Assessment
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DpiaAssessment {
    /// Assessment ID
    pub id: String,

    /// Processing activity
    pub processing_activity: String,

    /// Assessment date
    pub assessed_at: DateTime<Utc>,

    /// Risk level
    pub risk_level: RiskLevel,

    /// Mitigation measures
    pub mitigations: Vec<String>,

    /// Approved
    pub approved: bool,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_compliance_status_ordering() {
        assert!(RiskLevel::Low < RiskLevel::High);
        assert!(RiskLevel::VeryHigh > RiskLevel::Medium);
    }

    #[test]
    fn test_erasure_reason_serialization() {
        let reason = ErasureReason::UserRequest;
        let json = serde_json::to_string(&reason).unwrap();
        assert_eq!(json, r#""user_request""#);
    }

    #[test]
    fn test_incident_severity() {
        let severity = IncidentSeverity::Critical;
        assert_eq!(severity, IncidentSeverity::Critical);
    }
}
