package domain

import "time"

type Principal struct {
	Subject string `json:"subject"`
	Email   string `json:"email,omitempty"`
	Name    string `json:"name,omitempty"`
	Role    string `json:"role"`
}

type DashboardKPI struct {
	Code  string `json:"code"`
	Label string `json:"label"`
	Value string `json:"value"`
}

type UpcomingBooking struct {
	Reference     string    `json:"reference"`
	CustomerName  string    `json:"customerName"`
	CustomerEmail string    `json:"customerEmail"`
	StartsAt      time.Time `json:"startsAt"`
	EndsAt        time.Time `json:"endsAt"`
	Status        string    `json:"status"`
	Label         string    `json:"label,omitempty"`
}

type WidgetSnippet struct {
	Kind string `json:"kind"`
	Code string `json:"code"`
}

type TrackingStatus struct {
	Provider  string `json:"provider"`
	Connected bool   `json:"connected"`
	SiteID    string `json:"siteId,omitempty"`
	Message   string `json:"message,omitempty"`
}

type DashboardSummary struct {
	TenantName       string            `json:"tenantName"`
	TenantSlug       string            `json:"tenantSlug"`
	Locale           string            `json:"locale"`
	Timezone         string            `json:"timezone"`
	PlanCode         string            `json:"planCode"`
	PublicBookingURL string            `json:"publicBookingUrl"`
	SetupCompletion  int               `json:"setupCompletion"`
	KPIs             []DashboardKPI    `json:"kpis"`
	UpcomingBookings []UpcomingBooking `json:"upcomingBookings"`
	WidgetSnippets   []WidgetSnippet   `json:"widgetSnippets"`
	Tracking         TrackingStatus    `json:"tracking"`
}

type BrandProfile struct {
	Name         string `json:"name"`
	SiteURL      string `json:"siteUrl,omitempty"`
	LogoURL      string `json:"logoUrl,omitempty"`
	PrimaryColor string `json:"primaryColor,omitempty"`
}

type TenantBootstrap struct {
	TenantID            string       `json:"tenantId"`
	TenantName          string       `json:"tenantName"`
	TenantSlug          string       `json:"tenantSlug,omitempty"`
	Preset              string       `json:"preset"`
	Locale              string       `json:"locale"`
	Timezone            string       `json:"timezone"`
	PlanCode            string       `json:"planCode,omitempty"`
	OnboardingCompleted bool         `json:"onboardingCompleted"`
	Brand               BrandProfile `json:"brand"`
	CurrentUser         Principal    `json:"currentUser"`
}

type TeamInviteRequest struct {
	Email string `json:"email"`
	Role  string `json:"role,omitempty"`
}

type AvailabilityBlockRequest struct {
	DayOfWeek   int    `json:"dayOfWeek"`
	StartsLocal string `json:"startsLocal"`
	EndsLocal   string `json:"endsLocal"`
	Busy        bool   `json:"busy,omitempty"`
}

type BookingDefaultsRequest struct {
	ServiceName         string `json:"serviceName"`
	DurationMinutes     int    `json:"durationMinutes"`
	BufferBeforeMinutes int    `json:"bufferBeforeMinutes"`
	BufferAfterMinutes  int    `json:"bufferAfterMinutes"`
	CancelWindowHours   int    `json:"cancelWindowHours"`
}

type OnboardTenantRequest struct {
	Name               string                     `json:"name"`
	Slug               string                     `json:"slug"`
	Preset             string                     `json:"preset"`
	Locale             string                     `json:"locale"`
	Timezone           string                     `json:"timezone"`
	Brand              BrandProfile               `json:"brand"`
	LocationName       string                     `json:"locationName"`
	BookingDefaults    BookingDefaultsRequest     `json:"bookingDefaults"`
	AvailabilityBlocks []AvailabilityBlockRequest `json:"availabilityBlocks"`
	TeamInvites        []TeamInviteRequest        `json:"teamInvites"`
}

type TimeSlot struct {
	ServiceID         *string `json:"serviceId,omitempty"`
	ClassSessionID    *string `json:"classSessionId,omitempty"`
	StaffID           *string `json:"staffId,omitempty"`
	LocationID        *string `json:"locationId,omitempty"`
	StartsAt          string  `json:"startsAt"`
	EndsAt            string  `json:"endsAt"`
	Mode              string  `json:"mode"`
	Label             string  `json:"label"`
	RemainingCapacity *int32  `json:"remainingCapacity,omitempty"`
}

type PublicAvailability struct {
	TenantSlug string     `json:"tenantSlug"`
	Timezone   string     `json:"timezone"`
	Locale     string     `json:"locale"`
	Slots      []TimeSlot `json:"slots"`
}

type CreateBookingRequest struct {
	TenantSlug     string  `json:"tenantSlug"`
	BookingMode    string  `json:"bookingMode"`
	ServiceID      *string `json:"serviceId,omitempty"`
	ClassSessionID *string `json:"classSessionId,omitempty"`
	StaffID        *string `json:"staffId,omitempty"`
	LocationID     *string `json:"locationId,omitempty"`
	CustomerName   string  `json:"customerName"`
	CustomerEmail  string  `json:"customerEmail"`
	CustomerPhone  string  `json:"customerPhone,omitempty"`
	Notes          string  `json:"notes"`
	StartsAt       string  `json:"startsAt"`
	EndsAt         string  `json:"endsAt"`
}

type CreateBookingResponse struct {
	BookingID string `json:"bookingId"`
	Reference string `json:"reference"`
	Status    string `json:"status"`
}

type PlanEntitlements struct {
	MaxLocations      int  `json:"maxLocations"`
	MaxStaff          int  `json:"maxStaff"`
	MaxBookingsMonth  int  `json:"maxBookingsMonth"` // -1 = unlimited
	EmailReminders    bool `json:"emailReminders"`
	AdvancedReporting bool `json:"advancedReporting"`
	WidgetEmbedding   bool `json:"widgetEmbedding"`
	UmamiTracking     bool `json:"umamiTracking"`
	APIAccess         bool `json:"apiAccess"`
	DedicatedManager  bool `json:"dedicatedManager"`
	SMSAvailable      bool `json:"smsAvailable"`
}

type PlanPricing struct {
	MonthlyAmountCents   int    `json:"monthlyAmountCents"`
	YearlyAmountCents    int    `json:"yearlyAmountCents"`
	MonthlyFormatted     string `json:"monthlyFormatted"`
	YearlyFormatted      string `json:"yearlyFormatted"`
	YearlySavings        string `json:"yearlySavings"`
	YearlySavingsPercent int    `json:"yearlySavingsPercent"`
}

type PlanDisplayPrice struct {
	Currency             string `json:"currency"`
	AmountCents          int    `json:"amountCents"`
	Formatted            string `json:"formatted"`
	YearlyAmountCents    int    `json:"yearlyAmountCents,omitempty"`
	YearlyFormatted      string `json:"yearlyFormatted,omitempty"`
	YearlySavings        string `json:"yearlySavings,omitempty"`
	YearlySavingsPercent int    `json:"yearlySavingsPercent,omitempty"`
}

type SubscriptionSnapshot struct {
	TenantID             string             `json:"tenantId"`
	Provider             string             `json:"provider"`
	CustomerID           string             `json:"customerId"`
	SubscriptionID       string             `json:"subscriptionId"`
	Status               string             `json:"status"`
	PlanCode             string             `json:"planCode"`
	Currency             string             `json:"currency"`
	PriceID              string             `json:"priceId"`
	CancelAtPeriodEnd    bool               `json:"cancelAtPeriodEnd"`
	CurrentPeriodStart   *time.Time         `json:"currentPeriodStart,omitempty"`
	CurrentPeriodEnd     *time.Time         `json:"currentPeriodEnd,omitempty"`
	PaymentMethodBrand   string             `json:"paymentMethodBrand,omitempty"`
	PaymentMethodLast4   string             `json:"paymentMethodLast4,omitempty"`
	Entitlements         PlanEntitlements   `json:"entitlements"`
	DisplayPrices        []PlanDisplayPrice `json:"displayPrices"`
	TrialDays            int                `json:"trialDays"`
	LastSyncedAt         *time.Time         `json:"lastSyncedAt,omitempty"`
	CheckoutURLAvailable bool               `json:"checkoutUrlAvailable"`
	SyncAvailable        bool               `json:"syncAvailable"`
	PortalAvailable      bool               `json:"portalAvailable"`
}

type CheckoutSessionRequest struct {
	PlanCode        string `json:"planCode"`
	Currency        string `json:"currency,omitempty"`
	BillingInterval string `json:"billingInterval,omitempty"` // "monthly" or "yearly", defaults to "monthly"
}

type CheckoutLaunchResponse struct {
	// Stripe checkout
	CheckoutURL string `json:"checkoutUrl,omitempty"`
	// Paddle checkout
	PriceID       string `json:"priceId,omitempty"`
	CustomerID    string `json:"customerId,omitempty"`
	CustomerEmail string `json:"customerEmail,omitempty"`
	// Common
	SuccessRedirectURL string            `json:"successRedirectUrl,omitempty"`
	CancelRedirectURL  string            `json:"cancelRedirectUrl,omitempty"`
	CustomData         map[string]string `json:"customData,omitempty"`
}

type PortalSessionResponse struct {
	URL string `json:"url"`
}

type DispatchReminderJobsRequest struct {
	Limit int `json:"limit,omitempty"`
}

type DispatchReminderJobsResponse struct {
	ProcessedCount int `json:"processedCount"`
	SentCount      int `json:"sentCount"`
	FailedCount    int `json:"failedCount"`
}

// ============================================
// LOCATION / ZONE MODELS
// ============================================

type Location struct {
	ID        string    `json:"id"`
	TenantID  string    `json:"tenantId"`
	Name      string    `json:"name"`
	Type      string    `json:"type"` // room, private, hall, etc.
	Capacity  int       `json:"capacity"`
	Timezone  string    `json:"timezone"`
	CreatedAt time.Time `json:"createdAt"`
}

type CreateLocationRequest struct {
	Name     string `json:"name" binding:"required"`
	Type     string `json:"type" binding:"required"`
	Capacity int    `json:"capacity"`
}

type UpdateLocationRequest struct {
	Name     string `json:"name,omitempty"`
	Type     string `json:"type,omitempty"`
	Capacity int    `json:"capacity,omitempty"`
}

// ============================================
// BLOCKED DAYS / AVAILABILITY EXCEPTION MODELS
// ============================================

type BlockedDay struct {
	ID        string    `json:"id"`
	TenantID  string    `json:"tenantId"`
	Date      time.Time `json:"date"`
	Reason    string    `json:"reason"`
	Type      string    `json:"type"` // full, partial
	StaffID   *string   `json:"staffId,omitempty"`
	CreatedAt time.Time `json:"createdAt"`
}

type CreateBlockedDayRequest struct {
	Date    string  `json:"date" binding:"required"` // RFC3339
	Reason  string  `json:"reason" binding:"required"`
	Type    string  `json:"type" binding:"required"` // full, partial
	StaffID *string `json:"staffId,omitempty"`
}

type UpdateBlockedDayRequest struct {
	Reason string `json:"reason,omitempty"`
	Type   string `json:"type,omitempty"`
}

// ============================================
// CUSTOMER MODELS
// ============================================

type Customer struct {
	ID            string     `json:"id"`
	TenantID      string     `json:"tenantId"`
	Name          string     `json:"name"`
	Email         string     `json:"email"`
	Phone         *string    `json:"phone,omitempty"`
	Status        string     `json:"status"` // active, inactive, vip
	BookingsCount int        `json:"bookingsCount"`
	LastBookingAt *time.Time `json:"lastBookingAt,omitempty"`
	CreatedAt     time.Time  `json:"createdAt"`
	Notes         string     `json:"notes,omitempty"`
}

type CreateCustomerRequest struct {
	Name   string  `json:"name" binding:"required"`
	Email  string  `json:"email" binding:"required,email"`
	Phone  *string `json:"phone,omitempty"`
	Status string  `json:"status,omitempty"` // defaults to active
	Notes  string  `json:"notes,omitempty"`
}

type UpdateCustomerRequest struct {
	Name   string  `json:"name,omitempty"`
	Email  string  `json:"email,omitempty"`
	Phone  *string `json:"phone,omitempty"`
	Status string  `json:"status,omitempty"`
	Notes  string  `json:"notes,omitempty"`
}

// ============================================
// CUSTOMER BOOKING MANAGEMENT MODELS
// ============================================

type CustomerBookingView struct {
	Reference     string    `json:"reference"`
	CustomerName  string    `json:"customerName"`
	CustomerEmail string    `json:"customerEmail"`
	Service       string    `json:"service"`
	BusinessName  string    `json:"businessName"`
	StartsAt      time.Time `json:"startsAt"`
	EndsAt        time.Time `json:"endsAt"`
	Location      string    `json:"location"`
	Status        string    `json:"status"`
	Notes         string    `json:"notes,omitempty"`
}

type RescheduleBookingRequest struct {
	NewStartsAt string `json:"newStartsAt" binding:"required"` // RFC3339
	NewEndsAt   string `json:"newEndsAt" binding:"required"`   // RFC3339
	Reason      string `json:"reason,omitempty"`
}

type CancelBookingRequest struct {
	Reason string `json:"reason,omitempty"`
}

// ============================================
// ADMIN MODELS
// ============================================

type AdminDashboardStats struct {
	TotalTenants          int64 `json:"totalTenants"`
	TotalUsers            int64 `json:"totalUsers"`
	ActiveSubscriptions   int64 `json:"activeSubscriptions"`
	TrialSubscriptions    int64 `json:"trialSubscriptions"`
	BookingsThisMonth     int64 `json:"bookingsThisMonth"`
	RevenueThisMonthCents int64 `json:"revenueThisMonthCents"`
}

type AdminTenantList struct {
	Total    int           `json:"total"`
	Page     int           `json:"page"`
	PageSize int           `json:"pageSize"`
	Tenants  []AdminTenant `json:"tenants"`
}

type AdminTenant struct {
	ID                 string `json:"id"`
	Slug               string `json:"slug"`
	Name               string `json:"name"`
	PlanCode           string `json:"planCode"`
	SubscriptionStatus string `json:"subscriptionStatus"`
	BillingProvider    string `json:"billingProvider"`
}

type AdminUserList struct {
	Total    int         `json:"total"`
	Page     int         `json:"page"`
	PageSize int         `json:"pageSize"`
	Users    []AdminUser `json:"users"`
}

type AdminUser struct {
	ID            string    `json:"id"`
	Email         string    `json:"email"`
	Name          string    `json:"name,omitempty"`
	EmailVerified bool      `json:"emailVerified"`
	Provider      string    `json:"provider"`
	Role          string    `json:"role"`
	CreatedAt     time.Time `json:"createdAt"`
}

type AdminLoginRequest struct {
	Email string `json:"email" binding:"required,email"`
	Key   string `json:"key" binding:"required"`
}

type UpdateUserRoleRequest struct {
	Role string `json:"role" binding:"required,oneof=user admin superadmin"`
}

// ============================================
// WORKING HOURS MODELS
// ============================================

type WorkingHours struct {
	DayOfWeek int    `json:"dayOfWeek"` // 0=Sunday, 1=Monday, etc.
	Open      string `json:"open"`      // HH:MM format
	Close     string `json:"close"`     // HH:MM format
	IsOpen    bool   `json:"isOpen"`
}

type UpdateWorkingHoursRequest struct {
	Open   string `json:"open,omitempty"`
	Close  string `json:"close,omitempty"`
	IsOpen *bool  `json:"isOpen,omitempty"`
}

// ============================================
// EMAIL TEMPLATE MODELS
// ============================================

type EmailTemplate struct {
	ID        string `json:"id"`
	TenantID  string `json:"tenantId"`
	Type      string `json:"type"` // booking_confirmation, reminder, cancellation, etc.
	Subject   string `json:"subject"`
	BodyHTML  string `json:"bodyHtml"`
	BodyText  string `json:"bodyText"`
	IsEnabled bool   `json:"isEnabled"`
}

type SendEmailRequest struct {
	To      string            `json:"to" binding:"required,email"`
	Subject string            `json:"subject" binding:"required"`
	Body    string            `json:"body" binding:"required"`
	Data    map[string]string `json:"data,omitempty"` // Template variables
}

type EmailNotification struct {
	ID        string     `json:"id"`
	TenantID  string     `json:"tenantId"`
	BookingID string     `json:"bookingId,omitempty"`
	Channel   string     `json:"channel"` // email, sms
	Type      string     `json:"type"`    // confirmation, reminder, cancellation
	Recipient string     `json:"recipient"`
	Status    string     `json:"status"` // pending, sent, failed
	SentAt    *time.Time `json:"sentAt,omitempty"`
	Error     string     `json:"error,omitempty"`
	CreatedAt time.Time  `json:"createdAt"`
}

// ============================================
// SMS MODELS
// ============================================

type SMSSettings struct {
	Enabled        bool   `json:"enabled"`
	SenderName     string `json:"senderName,omitempty"`
	MonthlyLimit   int    `json:"monthlyLimit,omitempty"`
	MessagesSent   int    `json:"messagesSent"`
	TotalCostCents int    `json:"totalCostCents"`
	Available      bool   `json:"available"`
}

type UpdateSMSSettingsRequest struct {
	Enabled      bool   `json:"enabled"`
	SenderName   string `json:"senderName,omitempty"`
	MonthlyLimit int    `json:"monthlyLimit,omitempty"`
}

type SendSMSRequest struct {
	To   string `json:"to" binding:"required"`
	Body string `json:"body" binding:"required,max=1000"`
}

type SendSMSResponse struct {
	LogID     string `json:"logId"`
	MessageID string `json:"messageId,omitempty"`
	RequestID string `json:"requestId,omitempty"`
	Status    string `json:"status"`
	CostCents int    `json:"costCents"`
}

type SMSUsageLog struct {
	ID             string    `json:"id"`
	RecipientPhone string    `json:"recipientPhone"`
	MessageBody    string    `json:"messageBody,omitempty"`
	Status         string    `json:"status"`
	CostCents      int       `json:"costCents"`
	CreatedAt      time.Time `json:"createdAt"`
}

type SMSUsageReport struct {
	YearMonth       string     `json:"yearMonth"`
	MessageCount    int        `json:"messageCount"`
	TotalCostCents  int        `json:"totalCostCents"`
	StripeInvoiceID string     `json:"stripeInvoiceId,omitempty"`
	InvoiceSentAt   *time.Time `json:"invoiceSentAt,omitempty"`
}

type SMSInvoiceBatchResponse struct {
	YearMonth      string `json:"yearMonth"`
	ProcessedCount int    `json:"processedCount"`
	FailedCount    int    `json:"failedCount"`
}
