package models

import (
	"time"

	"github.com/google/uuid"
)

// ========================================
// DSGVO Betroffenenanfragen (DSR)
// Data Subject Request Management
// Art. 15, 16, 17, 18, 20 DSGVO
// ========================================

// DSRRequestType defines the GDPR article for the request
type DSRRequestType string

const (
	DSRTypeAccess       DSRRequestType = "access"       // Art. 15 - Auskunftsrecht
	DSRTypeRectification DSRRequestType = "rectification" // Art. 16 - Berichtigungsrecht
	DSRTypeErasure      DSRRequestType = "erasure"       // Art. 17 - Löschungsrecht
	DSRTypeRestriction  DSRRequestType = "restriction"   // Art. 18 - Einschränkungsrecht
	DSRTypePortability  DSRRequestType = "portability"   // Art. 20 - Datenübertragbarkeit
)

// DSRStatus defines the workflow state of a DSR
type DSRStatus string

const (
	DSRStatusIntake               DSRStatus = "intake"                // Eingegangen
	DSRStatusIdentityVerification DSRStatus = "identity_verification" // Identitätsprüfung
	DSRStatusProcessing           DSRStatus = "processing"            // In Bearbeitung
	DSRStatusCompleted            DSRStatus = "completed"             // Abgeschlossen
	DSRStatusRejected             DSRStatus = "rejected"              // Abgelehnt
	DSRStatusCancelled            DSRStatus = "cancelled"             // Storniert
)

// DSRPriority defines the priority level of a DSR
type DSRPriority string

const (
	DSRPriorityNormal   DSRPriority = "normal"
	DSRPriorityExpedited DSRPriority = "expedited" // Art. 16, 17, 18 - beschleunigt
	DSRPriorityUrgent   DSRPriority = "urgent"
)

// DSRSource defines where the request came from
type DSRSource string

const (
	DSRSourceAPI        DSRSource = "api"         // Über API/Self-Service
	DSRSourceAdminPanel DSRSource = "admin_panel" // Manuell im Admin
	DSRSourceEmail      DSRSource = "email"       // Per E-Mail
	DSRSourcePostal     DSRSource = "postal"      // Per Post
)

// Art. 17(3) Exception Types
const (
	DSRExceptionFreedomExpression = "freedom_expression" // Art. 17(3)(a)
	DSRExceptionLegalObligation   = "legal_obligation"   // Art. 17(3)(b)
	DSRExceptionPublicInterest    = "public_interest"    // Art. 17(3)(c)
	DSRExceptionPublicHealth      = "public_health"      // Art. 17(3)(c)
	DSRExceptionArchiving         = "archiving"          // Art. 17(3)(d)
	DSRExceptionLegalClaims       = "legal_claims"       // Art. 17(3)(e)
)

// DataSubjectRequest represents a GDPR data subject request
type DataSubjectRequest struct {
	ID                         uuid.UUID              `json:"id" db:"id"`
	UserID                     *uuid.UUID             `json:"user_id,omitempty" db:"user_id"`
	RequestNumber              string                 `json:"request_number" db:"request_number"`
	RequestType                DSRRequestType         `json:"request_type" db:"request_type"`
	Status                     DSRStatus              `json:"status" db:"status"`
	Priority                   DSRPriority            `json:"priority" db:"priority"`
	Source                     DSRSource              `json:"source" db:"source"`
	RequesterEmail             string                 `json:"requester_email" db:"requester_email"`
	RequesterName              *string                `json:"requester_name,omitempty" db:"requester_name"`
	RequesterPhone             *string                `json:"requester_phone,omitempty" db:"requester_phone"`
	IdentityVerified           bool                   `json:"identity_verified" db:"identity_verified"`
	IdentityVerifiedAt         *time.Time             `json:"identity_verified_at,omitempty" db:"identity_verified_at"`
	IdentityVerifiedBy         *uuid.UUID             `json:"identity_verified_by,omitempty" db:"identity_verified_by"`
	IdentityVerificationMethod *string                `json:"identity_verification_method,omitempty" db:"identity_verification_method"`
	RequestDetails             map[string]interface{} `json:"request_details" db:"request_details"`
	DeadlineAt                 time.Time              `json:"deadline_at" db:"deadline_at"`
	LegalDeadlineDays          int                    `json:"legal_deadline_days" db:"legal_deadline_days"`
	ExtendedDeadlineAt         *time.Time             `json:"extended_deadline_at,omitempty" db:"extended_deadline_at"`
	ExtensionReason            *string                `json:"extension_reason,omitempty" db:"extension_reason"`
	AssignedTo                 *uuid.UUID             `json:"assigned_to,omitempty" db:"assigned_to"`
	ProcessingNotes            *string                `json:"processing_notes,omitempty" db:"processing_notes"`
	CompletedAt                *time.Time             `json:"completed_at,omitempty" db:"completed_at"`
	CompletedBy                *uuid.UUID             `json:"completed_by,omitempty" db:"completed_by"`
	ResultSummary              *string                `json:"result_summary,omitempty" db:"result_summary"`
	ResultData                 map[string]interface{} `json:"result_data,omitempty" db:"result_data"`
	RejectedAt                 *time.Time             `json:"rejected_at,omitempty" db:"rejected_at"`
	RejectedBy                 *uuid.UUID             `json:"rejected_by,omitempty" db:"rejected_by"`
	RejectionReason            *string                `json:"rejection_reason,omitempty" db:"rejection_reason"`
	RejectionLegalBasis        *string                `json:"rejection_legal_basis,omitempty" db:"rejection_legal_basis"`
	CreatedAt                  time.Time              `json:"created_at" db:"created_at"`
	UpdatedAt                  time.Time              `json:"updated_at" db:"updated_at"`
	CreatedBy                  *uuid.UUID             `json:"created_by,omitempty" db:"created_by"`
}

// DSRStatusHistory tracks status changes for audit trail
type DSRStatusHistory struct {
	ID         uuid.UUID              `json:"id" db:"id"`
	RequestID  uuid.UUID              `json:"request_id" db:"request_id"`
	FromStatus *DSRStatus             `json:"from_status,omitempty" db:"from_status"`
	ToStatus   DSRStatus              `json:"to_status" db:"to_status"`
	ChangedBy  *uuid.UUID             `json:"changed_by,omitempty" db:"changed_by"`
	Comment    *string                `json:"comment,omitempty" db:"comment"`
	Metadata   map[string]interface{} `json:"metadata,omitempty" db:"metadata"`
	CreatedAt  time.Time              `json:"created_at" db:"created_at"`
}

// DSRCommunication tracks all communications related to a DSR
type DSRCommunication struct {
	ID                uuid.UUID                `json:"id" db:"id"`
	RequestID         uuid.UUID                `json:"request_id" db:"request_id"`
	Direction         string                   `json:"direction" db:"direction"`
	Channel           string                   `json:"channel" db:"channel"`
	CommunicationType string                   `json:"communication_type" db:"communication_type"`
	TemplateVersionID *uuid.UUID               `json:"template_version_id,omitempty" db:"template_version_id"`
	Subject           *string                  `json:"subject,omitempty" db:"subject"`
	BodyHTML          *string                  `json:"body_html,omitempty" db:"body_html"`
	BodyText          *string                  `json:"body_text,omitempty" db:"body_text"`
	RecipientEmail    *string                  `json:"recipient_email,omitempty" db:"recipient_email"`
	SentAt            *time.Time               `json:"sent_at,omitempty" db:"sent_at"`
	ErrorMessage      *string                  `json:"error_message,omitempty" db:"error_message"`
	Attachments       []map[string]interface{} `json:"attachments,omitempty" db:"attachments"`
	CreatedAt         time.Time                `json:"created_at" db:"created_at"`
	CreatedBy         *uuid.UUID               `json:"created_by,omitempty" db:"created_by"`
}

// DSRTemplate represents a template type for DSR communications
type DSRTemplate struct {
	ID           uuid.UUID `json:"id" db:"id"`
	TemplateType string    `json:"template_type" db:"template_type"`
	Name         string    `json:"name" db:"name"`
	Description  *string   `json:"description,omitempty" db:"description"`
	RequestTypes []string  `json:"request_types" db:"request_types"`
	IsActive     bool      `json:"is_active" db:"is_active"`
	SortOrder    int       `json:"sort_order" db:"sort_order"`
	CreatedAt    time.Time `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time `json:"updated_at" db:"updated_at"`
}

// DSRTemplateVersion represents a versioned template for DSR communications
type DSRTemplateVersion struct {
	ID          uuid.UUID  `json:"id" db:"id"`
	TemplateID  uuid.UUID  `json:"template_id" db:"template_id"`
	Version     string     `json:"version" db:"version"`
	Language    string     `json:"language" db:"language"`
	Subject     string     `json:"subject" db:"subject"`
	BodyHTML    string     `json:"body_html" db:"body_html"`
	BodyText    string     `json:"body_text" db:"body_text"`
	Status      string     `json:"status" db:"status"`
	PublishedAt *time.Time `json:"published_at,omitempty" db:"published_at"`
	CreatedBy   *uuid.UUID `json:"created_by,omitempty" db:"created_by"`
	ApprovedBy  *uuid.UUID `json:"approved_by,omitempty" db:"approved_by"`
	ApprovedAt  *time.Time `json:"approved_at,omitempty" db:"approved_at"`
	CreatedAt   time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at" db:"updated_at"`
}

// DSRExceptionCheck tracks Art. 17(3) exception evaluations for erasure requests
type DSRExceptionCheck struct {
	ID            uuid.UUID  `json:"id" db:"id"`
	RequestID     uuid.UUID  `json:"request_id" db:"request_id"`
	ExceptionType string     `json:"exception_type" db:"exception_type"`
	Description   string     `json:"description" db:"description"`
	Applies       *bool      `json:"applies,omitempty" db:"applies"`
	CheckedBy     *uuid.UUID `json:"checked_by,omitempty" db:"checked_by"`
	CheckedAt     *time.Time `json:"checked_at,omitempty" db:"checked_at"`
	Notes         *string    `json:"notes,omitempty" db:"notes"`
	CreatedAt     time.Time  `json:"created_at" db:"created_at"`
}

// ========================================
// DSR DTOs
// ========================================

// CreateDSRRequest for creating a new data subject request
type CreateDSRRequest struct {
	RequestType    string                 `json:"request_type" binding:"required"`
	RequesterEmail string                 `json:"requester_email" binding:"required,email"`
	RequesterName  *string                `json:"requester_name"`
	RequesterPhone *string                `json:"requester_phone"`
	Source         string                 `json:"source"`
	RequestDetails map[string]interface{} `json:"request_details"`
	Priority       string                 `json:"priority"`
}

// UpdateDSRRequest for updating a DSR
type UpdateDSRRequest struct {
	Status          *string                `json:"status"`
	AssignedTo      *string                `json:"assigned_to"`
	ProcessingNotes *string                `json:"processing_notes"`
	ExtendDeadline  *bool                  `json:"extend_deadline"`
	ExtensionReason *string                `json:"extension_reason"`
	RequestDetails  map[string]interface{} `json:"request_details"`
	Priority        *string                `json:"priority"`
}

// VerifyDSRIdentityRequest for verifying identity of requester
type VerifyDSRIdentityRequest struct {
	Method  string  `json:"method" binding:"required"`
	Comment *string `json:"comment"`
}

// CompleteDSRRequest for completing a DSR
type CompleteDSRRequest struct {
	ResultSummary string                 `json:"result_summary" binding:"required"`
	ResultData    map[string]interface{} `json:"result_data"`
}

// RejectDSRRequest for rejecting a DSR
type RejectDSRRequest struct {
	Reason     string `json:"reason" binding:"required"`
	LegalBasis string `json:"legal_basis" binding:"required"`
}

// ExtendDSRDeadlineRequest for extending a DSR deadline
type ExtendDSRDeadlineRequest struct {
	Reason string `json:"reason" binding:"required"`
	Days   int    `json:"days"`
}

// AssignDSRRequest for assigning a DSR to a handler
type AssignDSRRequest struct {
	AssigneeID string  `json:"assignee_id" binding:"required"`
	Comment    *string `json:"comment"`
}

// SendDSRCommunicationRequest for sending a communication
type SendDSRCommunicationRequest struct {
	CommunicationType string            `json:"communication_type" binding:"required"`
	TemplateVersionID *string           `json:"template_version_id"`
	CustomSubject     *string           `json:"custom_subject"`
	CustomBody        *string           `json:"custom_body"`
	Variables         map[string]string `json:"variables"`
}

// UpdateDSRExceptionCheckRequest for updating an exception check
type UpdateDSRExceptionCheckRequest struct {
	Applies bool    `json:"applies"`
	Notes   *string `json:"notes"`
}

// DSRListFilters for filtering DSR list
type DSRListFilters struct {
	Status      *string    `form:"status"`
	RequestType *string    `form:"request_type"`
	AssignedTo  *string    `form:"assigned_to"`
	Priority    *string    `form:"priority"`
	OverdueOnly bool       `form:"overdue_only"`
	FromDate    *time.Time `form:"from_date"`
	ToDate      *time.Time `form:"to_date"`
	Search      *string    `form:"search"`
}

// DSRDashboardStats for the admin dashboard
type DSRDashboardStats struct {
	TotalRequests         int                  `json:"total_requests"`
	PendingRequests       int                  `json:"pending_requests"`
	OverdueRequests       int                  `json:"overdue_requests"`
	CompletedThisMonth    int                  `json:"completed_this_month"`
	AverageProcessingDays float64              `json:"average_processing_days"`
	ByType                map[string]int       `json:"by_type"`
	ByStatus              map[string]int       `json:"by_status"`
	UpcomingDeadlines     []DataSubjectRequest `json:"upcoming_deadlines"`
}

// DSRWithDetails combines DSR with related data
type DSRWithDetails struct {
	Request         DataSubjectRequest  `json:"request"`
	StatusHistory   []DSRStatusHistory  `json:"status_history"`
	Communications  []DSRCommunication  `json:"communications"`
	ExceptionChecks []DSRExceptionCheck `json:"exception_checks,omitempty"`
	AssigneeName    *string             `json:"assignee_name,omitempty"`
	CreatorName     *string             `json:"creator_name,omitempty"`
}

// DSRTemplateWithVersions combines template with versions
type DSRTemplateWithVersions struct {
	Template      DSRTemplate          `json:"template"`
	LatestVersion *DSRTemplateVersion  `json:"latest_version,omitempty"`
	Versions      []DSRTemplateVersion `json:"versions,omitempty"`
}

// CreateDSRTemplateVersionRequest for creating a template version
type CreateDSRTemplateVersionRequest struct {
	TemplateID string `json:"template_id" binding:"required"`
	Version    string `json:"version" binding:"required"`
	Language   string `json:"language" binding:"required"`
	Subject    string `json:"subject" binding:"required"`
	BodyHTML   string `json:"body_html" binding:"required"`
	BodyText   string `json:"body_text" binding:"required"`
}

// UpdateDSRTemplateVersionRequest for updating a template version
type UpdateDSRTemplateVersionRequest struct {
	Subject  *string `json:"subject"`
	BodyHTML *string `json:"body_html"`
	BodyText *string `json:"body_text"`
	Status   *string `json:"status"`
}

// PreviewDSRTemplateRequest for previewing a template with variables
type PreviewDSRTemplateRequest struct {
	Variables map[string]string `json:"variables"`
}

// DSRTemplatePreviewResponse for template preview
type DSRTemplatePreviewResponse struct {
	Subject  string `json:"subject"`
	BodyHTML string `json:"body_html"`
	BodyText string `json:"body_text"`
}

// ========================================
// DSR Helper Methods
// ========================================

// Label returns German label for request type
func (rt DSRRequestType) Label() string {
	switch rt {
	case DSRTypeAccess:
		return "Auskunftsanfrage (Art. 15)"
	case DSRTypeRectification:
		return "Berichtigungsanfrage (Art. 16)"
	case DSRTypeErasure:
		return "Löschanfrage (Art. 17)"
	case DSRTypeRestriction:
		return "Einschränkungsanfrage (Art. 18)"
	case DSRTypePortability:
		return "Datenübertragung (Art. 20)"
	default:
		return string(rt)
	}
}

// DeadlineDays returns the legal deadline in days for request type
func (rt DSRRequestType) DeadlineDays() int {
	switch rt {
	case DSRTypeAccess, DSRTypePortability:
		return 30 // 1 month
	case DSRTypeRectification, DSRTypeErasure, DSRTypeRestriction:
		return 14 // 2 weeks (expedited per BDSG)
	default:
		return 30
	}
}

// IsExpedited returns whether this request type should be processed expeditiously
func (rt DSRRequestType) IsExpedited() bool {
	switch rt {
	case DSRTypeRectification, DSRTypeErasure, DSRTypeRestriction:
		return true
	default:
		return false
	}
}

// Label returns German label for status
func (s DSRStatus) Label() string {
	switch s {
	case DSRStatusIntake:
		return "Eingang"
	case DSRStatusIdentityVerification:
		return "Identitätsprüfung"
	case DSRStatusProcessing:
		return "In Bearbeitung"
	case DSRStatusCompleted:
		return "Abgeschlossen"
	case DSRStatusRejected:
		return "Abgelehnt"
	case DSRStatusCancelled:
		return "Storniert"
	default:
		return string(s)
	}
}

// IsValidDSRRequestType checks if a string is a valid DSR request type
func IsValidDSRRequestType(reqType string) bool {
	switch DSRRequestType(reqType) {
	case DSRTypeAccess, DSRTypeRectification, DSRTypeErasure, DSRTypeRestriction, DSRTypePortability:
		return true
	default:
		return false
	}
}

// IsValidDSRStatus checks if a string is a valid DSR status
func IsValidDSRStatus(status string) bool {
	switch DSRStatus(status) {
	case DSRStatusIntake, DSRStatusIdentityVerification, DSRStatusProcessing,
		DSRStatusCompleted, DSRStatusRejected, DSRStatusCancelled:
		return true
	default:
		return false
	}
}
