package models

import (
	"time"

	"github.com/google/uuid"
)

type DateRange struct {
	From time.Time `json:"from"`
	To   time.Time `json:"to"`
}

// Warmup Analytics

type WarmupAnalytics struct {
	EmailAccountID uuid.UUID          `json:"email_account_id"`
	Email          string             `json:"email"`
	DateRange      DateRange          `json:"date_range"`
	Summary        WarmupSummary      `json:"summary"`
	DailyStats     []WarmupDailyStats `json:"daily_stats"`
}

type WarmupSummary struct {
	TotalSent      int     `json:"total_sent"`
	TotalReplied   int     `json:"total_replied"`
	AverageDaily   float64 `json:"average_daily"`
	ReplyRate      float64 `json:"reply_rate"`      // percentage
	TargetProgress float64 `json:"target_progress"` // percentage to max
	DaysActive     int     `json:"days_active"`
}

type WarmupDailyStats struct {
	Date          string `json:"date"` // YYYY-MM-DD
	EmailsSent    int    `json:"emails_sent"`
	EmailsReplied int    `json:"emails_replied"`
	TargetVolume  int    `json:"target_volume"`
}

// Campaign Analytics

type CampaignAnalytics struct {
	CampaignID uuid.UUID            `json:"campaign_id"`
	Name       string               `json:"name"`
	Status     string               `json:"status"`
	DateRange  DateRange            `json:"date_range"`
	Summary    CampaignSummary      `json:"summary"`
	Sequences  []SequenceStats      `json:"steps"`
	DailyStats []CampaignDailyStats `json:"daily_stats,omitempty"`
	// Engagement is where and on what people opened and clicked, from the
	// per-event logs. Human events only.
	Engagement *CampaignEngagementBreakdown `json:"engagement,omitempty"`
}

// EngagementBucket is one slice of a breakdown: how many distinct contacts
// opened and clicked from that country, client, or device.
type EngagementBucket struct {
	Key    string `json:"key"`
	Opens  int    `json:"opens"`
	Clicks int    `json:"clicks"`
}

// CampaignEngagementBreakdown is the "where from, on what" view of a
// campaign's human opens and clicks. Buckets are ordered by activity, capped,
// and keyed by ISO country code, client or browser name, and device type.
// Unknown is the empty key.
type CampaignEngagementBreakdown struct {
	Countries []EngagementBucket `json:"countries"`
	Clients   []EngagementBucket `json:"clients"`
	Devices   []EngagementBucket `json:"devices"`
}

type CampaignSummary struct {
	TotalContacts int `json:"total_contacts"`
	EmailsSent    int `json:"emails_sent"`
	EmailsPending int `json:"emails_pending"`
	UniqueOpens   int `json:"unique_opens"`
	// MachineOpens is the subset of UniqueOpens from automated fetchers
	// (Apple MPP prefetch, UA-less clients). Human opens = unique - machine.
	MachineOpens int `json:"machine_opens"`
	UniqueClicks int `json:"unique_clicks"`
	// MachineClicks counts steps whose only clicks came from automated
	// fetchers (security gateways walking the links). They are not part of
	// UniqueClicks, which only ever counts a person's click.
	MachineClicks int `json:"machine_clicks"`
	Replies       int `json:"replies"`
	Bounces       int `json:"bounces"`
	Unsubscribes  int `json:"unsubscribes"`

	OpenRate   float64 `json:"open_rate"`   // percentage
	ClickRate  float64 `json:"click_rate"`  // percentage
	ReplyRate  float64 `json:"reply_rate"`  // percentage
	BounceRate float64 `json:"bounce_rate"` // percentage
}

type SequenceStats struct {
	SequenceID uuid.UUID `json:"step_id"`
	Name       string    `json:"name"`
	Position   int       `json:"position"`
	EmailsSent int       `json:"emails_sent"`
	Opens      int       `json:"opens"`
	Clicks     int       `json:"clicks"`
	Replies    int       `json:"replies"`
	Bounces    int       `json:"bounces"`
}

type CampaignDailyStats struct {
	Date    string `json:"date"`
	Sent    int    `json:"sent"`
	Opens   int    `json:"opens"`
	Clicks  int    `json:"clicks"`
	Replies int    `json:"replies"`
}

// Email Account Status

type EmailAccountStatus struct {
	ID           uuid.UUID         `json:"id"`
	Email        string            `json:"email"`
	Provider     string            `json:"provider"`
	Status       string            `json:"status"`
	LastSyncedAt *time.Time        `json:"last_synced_at"`
	Health       AccountHealth     `json:"health"`
	Errors       []AccountError    `json:"errors"`
	DailyUsage   AccountDailyUsage `json:"daily_usage"`
	WarmupStatus *WarmupStatusInfo `json:"warmup_status,omitempty"`
	// WarmupHealth is the mailbox's warmup-pool reputation (spam placement,
	// complaints, throttle/quarantine state). Folded into Health.Score and
	// also exposed in detail here. Nil when the mailbox is not in a pool.
	WarmupHealth *WarmupHealthInfo `json:"warmup_health,omitempty"`
	// InCampaign reports whether the mailbox currently backs a live campaign.
	// When true a low-volume health-check warmup keeps running even if the
	// user has warmup paused/off.
	InCampaign bool `json:"in_campaign"`
	// SendLifecycle is whether the mailbox is in cold rotation, present only
	// when it is NOT: an active mailbox needs no explanation.
	SendLifecycle *SendLifecycleState `json:"send_lifecycle,omitempty"`
	// ColdRamp is the warmup-to-cold graduation ceiling, present only while it
	// is below the mailbox's own cap. Without it the cap just reads lower than
	// the number the owner configured.
	ColdRamp *ColdRampInfo `json:"cold_ramp,omitempty"`
}

// ColdRampInfo explains a cold cap held below the mailbox's configured limit.
type ColdRampInfo struct {
	// Ceiling is today's allowance; MailboxCap is what the owner configured.
	Ceiling    int `json:"ceiling"`
	MailboxCap int `json:"mailbox_cap"`
	// DaysToFullCap is how many clean days remain before Ceiling reaches
	// MailboxCap, 0 when it arrives today.
	DaysToFullCap int `json:"days_to_full_cap"`
	// Held is set when a recent spam placement is pausing the climb.
	Held bool `json:"held"`
}

type WarmupHealthInfo struct {
	State        string     `json:"state"` // healthy/watch/throttled/quarantined/blocked
	Score        float64    `json:"score"`
	Reason       string     `json:"reason,omitempty"`
	SpamScore    int        `json:"spam_score"`
	BlockedUntil *time.Time `json:"blocked_until,omitempty"`
	EvaluatedAt  *time.Time `json:"evaluated_at,omitempty"`
}

type AccountHealth struct {
	Status string   `json:"status"` // healthy, warning, error
	Score  int      `json:"score"`  // 0-100
	Issues []string `json:"issues,omitempty"`
}

type AccountError struct {
	ID             uuid.UUID `json:"id"`
	ErrorCode      string    `json:"error_code"`
	Severity       string    `json:"severity"`
	Title          string    `json:"title"`
	Message        string    `json:"message"`
	ActionRequired *string   `json:"action_required,omitempty"`
	CreatedAt      time.Time `json:"created_at"`
}

type AccountDailyUsage struct {
	Date          string `json:"date"`
	CampaignSent  int    `json:"campaign_sent"`
	CampaignLimit int    `json:"campaign_limit"`
	WarmupSent    int    `json:"warmup_sent,omitempty"`
	WarmupLimit   int    `json:"warmup_limit,omitempty"`
}

type WarmupStatusInfo struct {
	Enabled       bool       `json:"enabled"`
	Paused        bool       `json:"paused"`
	PausedAt      *time.Time `json:"paused_at,omitempty"`
	StartedAt     time.Time  `json:"started_at"`
	CurrentVolume int        `json:"current_volume"`
	TargetVolume  int        `json:"target_volume"`
	MaxVolume     int        `json:"max_volume"`
	ReplyRate     int        `json:"reply_rate"`
	DaysActive    int        `json:"days_active"`
	// RampHold explains a ramp that is not climbing, so a target below the
	// plain ramp is never an unexplained drop.
	RampHold *WarmupRampHold `json:"ramp_hold,omitempty"`
}

// WarmupRampHold explains a ramp that is not climbing. Present for the whole
// freeze; VolumeCut says whether today's volume is also reduced, which lasts a
// shorter window.
type WarmupRampHold struct {
	// Placements and Sends cover the last 48 hours.
	Placements int  `json:"placements"`
	Sends      int  `json:"sends"`
	VolumeCut  bool `json:"volume_cut"`
	// ResumesAt is when the ramp climbs again if nothing else lands.
	ResumesAt time.Time `json:"resumes_at"`
}

// Usage Overview

type UsageOverview struct {
	UserID uuid.UUID `json:"user_id"`
	Period string    `json:"period"` // day, week, month

	EmailAccounts AccountsUsage  `json:"email_accounts"`
	Campaigns     CampaignsUsage `json:"campaigns"`
	Contacts      ContactsUsage  `json:"contacts"`
	API           APIUsage       `json:"api"`
}

type AccountsUsage struct {
	Total      int `json:"total"`
	Active     int `json:"active"`
	InWarmup   int `json:"in_warmup"`
	WithErrors int `json:"with_errors"`
}

type CampaignsUsage struct {
	Total      int `json:"total"`
	Active     int `json:"active"`
	Paused     int `json:"paused"`
	Draft      int `json:"draft"`
	EmailsSent int `json:"emails_sent"`
}

type ContactsUsage struct {
	Total      int `json:"total"`
	Subscribed int `json:"subscribed"`
	AddedToday int `json:"added_today"`
}

type APIUsage struct {
	TotalCalls   int             `json:"total_calls"`
	DailyLimit   int             `json:"daily_limit"`
	TopEndpoints []EndpointUsage `json:"top_endpoints"`
}

type EndpointUsage struct {
	Endpoint string `json:"endpoint"`
	Calls    int    `json:"calls"`
}

// Dashboard Analytics

// DashboardAnalytics is the main dashboard overview combining multiple stats
type DashboardAnalytics struct {
	Period         string                `json:"period"` // 7d, 30d, 90d
	OverallStats   DashboardOverallStats `json:"overall_stats"`
	RecentActivity []RecentActivityItem  `json:"recent_activity"`
	TopCampaigns   []TopCampaignStats    `json:"top_campaigns"`
	AccountHealth  AccountHealthSummary  `json:"account_health"`
	DailyTrend     []DashboardDailyStats `json:"daily_trend"`
}

// DashboardOverallStats contains aggregate statistics for the dashboard
type DashboardOverallStats struct {
	TotalEmailsSent int `json:"total_emails_sent"`
	TotalOpens      int `json:"total_opens"`
	// MachineOpens is the subset of TotalOpens from automated fetchers.
	MachineOpens int `json:"machine_opens"`
	TotalClicks  int `json:"total_clicks"`
	// MachineClicks counts steps clicked only by automated fetchers; they are
	// not part of TotalClicks.
	MachineClicks   int     `json:"machine_clicks"`
	TotalReplies    int     `json:"total_replies"`
	TotalBounces    int     `json:"total_bounces"`
	OpenRate        float64 `json:"open_rate"`
	ClickRate       float64 `json:"click_rate"`
	ReplyRate       float64 `json:"reply_rate"`
	BounceRate      float64 `json:"bounce_rate"`
	ActiveCampaigns int     `json:"active_campaigns"`
	ActiveAccounts  int     `json:"active_accounts"`
}

// RecentActivityItem represents a single activity event
type RecentActivityItem struct {
	Type         string    `json:"type"` // opened, clicked, replied, bounced, sent
	CampaignID   uuid.UUID `json:"campaign_id"`
	CampaignName string    `json:"campaign_name"`
	ContactEmail string    `json:"contact_email"`
	ContactID    uuid.UUID `json:"contact_id,omitempty"`
	Timestamp    time.Time `json:"timestamp"`
	Link         string    `json:"link,omitempty"` // For click events
}

// TopCampaignStats represents performance stats for a top campaign
type TopCampaignStats struct {
	CampaignID uuid.UUID `json:"campaign_id"`
	Name       string    `json:"name"`
	Status     string    `json:"status"`
	EmailsSent int       `json:"emails_sent"`
	OpenRate   float64   `json:"open_rate"`
	ClickRate  float64   `json:"click_rate"`
	ReplyRate  float64   `json:"reply_rate"`
}

// AccountHealthSummary provides a summary of all email account health
type AccountHealthSummary struct {
	TotalAccounts   int `json:"total_accounts"`
	HealthyAccounts int `json:"healthy_accounts"`
	WarningAccounts int `json:"warning_accounts"`
	ErrorAccounts   int `json:"error_accounts"`
}

// DashboardDailyStats represents daily statistics for trend charts
type DashboardDailyStats struct {
	Date    string `json:"date"` // YYYY-MM-DD
	Sent    int    `json:"sent"`
	Opens   int    `json:"opens"`
	Clicks  int    `json:"clicks"`
	Replies int    `json:"replies"`
}

// CampaignHourlyStats represents hourly statistics for a campaign
type CampaignHourlyStats struct {
	Hour    int `json:"hour"` // 0-23
	Sent    int `json:"sent"`
	Opens   int `json:"opens"`
	Clicks  int `json:"clicks"`
	Replies int `json:"replies"`
}

// CampaignComparison allows comparing multiple campaigns
type CampaignComparison struct {
	Campaigns []CampaignComparisonItem `json:"campaigns"`
	Period    DateRange                `json:"period"`
}

// CampaignComparisonItem represents a single campaign in a comparison
type CampaignComparisonItem struct {
	CampaignID uuid.UUID `json:"campaign_id"`
	Name       string    `json:"name"`
	Status     string    `json:"status"`
	EmailsSent int       `json:"emails_sent"`
	OpenRate   float64   `json:"open_rate"`
	ClickRate  float64   `json:"click_rate"`
	ReplyRate  float64   `json:"reply_rate"`
	BounceRate float64   `json:"bounce_rate"`
}
