package handler

import (
	"github.com/warmbly/warmbly/internal/app/admin"
	"github.com/warmbly/warmbly/internal/app/adminoutreach"
	"github.com/warmbly/warmbly/internal/app/advanced"
	"github.com/warmbly/warmbly/internal/app/advisor"
	"github.com/warmbly/warmbly/internal/app/aiagent"
	"github.com/warmbly/warmbly/internal/app/aitools"
	"github.com/warmbly/warmbly/internal/app/analytics"
	"github.com/warmbly/warmbly/internal/app/apikey"
	"github.com/warmbly/warmbly/internal/app/audit"
	"github.com/warmbly/warmbly/internal/app/auth"
	"github.com/warmbly/warmbly/internal/app/behavior"
	"github.com/warmbly/warmbly/internal/app/bootstrap"
	"github.com/warmbly/warmbly/internal/app/campaign"
	"github.com/warmbly/warmbly/internal/app/cliauth"
	"github.com/warmbly/warmbly/internal/app/cloudlink"
	"github.com/warmbly/warmbly/internal/app/compose"
	"github.com/warmbly/warmbly/internal/app/contact"
	"github.com/warmbly/warmbly/internal/app/credits"
	"github.com/warmbly/warmbly/internal/app/crm"
	"github.com/warmbly/warmbly/internal/app/dangerzone"
	"github.com/warmbly/warmbly/internal/app/discount"
	"github.com/warmbly/warmbly/internal/app/email"
	"github.com/warmbly/warmbly/internal/app/emailsend"
	emailverifyapp "github.com/warmbly/warmbly/internal/app/emailverify"
	"github.com/warmbly/warmbly/internal/app/feature"
	"github.com/warmbly/warmbly/internal/app/form"
	"github.com/warmbly/warmbly/internal/app/group"
	"github.com/warmbly/warmbly/internal/app/instancecheck"
	"github.com/warmbly/warmbly/internal/app/instanceconfig"
	"github.com/warmbly/warmbly/internal/app/instancesettings"
	"github.com/warmbly/warmbly/internal/app/integration"
	"github.com/warmbly/warmbly/internal/app/leadsync"
	"github.com/warmbly/warmbly/internal/app/mcp"
	"github.com/warmbly/warmbly/internal/app/notification"
	"github.com/warmbly/warmbly/internal/app/oauth"
	"github.com/warmbly/warmbly/internal/app/opsnotify"
	"github.com/warmbly/warmbly/internal/app/organization"
	"github.com/warmbly/warmbly/internal/app/orgrisk"
	"github.com/warmbly/warmbly/internal/app/orgtransfer"
	"github.com/warmbly/warmbly/internal/app/passkey"
	"github.com/warmbly/warmbly/internal/app/placement"
	"github.com/warmbly/warmbly/internal/app/poollink"
	"github.com/warmbly/warmbly/internal/app/ratelimit"
	"github.com/warmbly/warmbly/internal/app/referral"
	"github.com/warmbly/warmbly/internal/app/releases"
	"github.com/warmbly/warmbly/internal/app/research"
	"github.com/warmbly/warmbly/internal/app/segment"
	"github.com/warmbly/warmbly/internal/app/sequence"
	"github.com/warmbly/warmbly/internal/app/skills"
	"github.com/warmbly/warmbly/internal/app/socket"
	"github.com/warmbly/warmbly/internal/app/stripe"
	"github.com/warmbly/warmbly/internal/app/subscription"
	"github.com/warmbly/warmbly/internal/app/sysstatus"
	"github.com/warmbly/warmbly/internal/app/team"
	"github.com/warmbly/warmbly/internal/app/template"
	"github.com/warmbly/warmbly/internal/app/token"
	"github.com/warmbly/warmbly/internal/app/trial"
	"github.com/warmbly/warmbly/internal/app/twofa"
	"github.com/warmbly/warmbly/internal/app/tz"
	"github.com/warmbly/warmbly/internal/app/unibox"
	"github.com/warmbly/warmbly/internal/app/unsublink"
	"github.com/warmbly/warmbly/internal/app/updates"
	"github.com/warmbly/warmbly/internal/app/user"
	"github.com/warmbly/warmbly/internal/app/warmup"
	"github.com/warmbly/warmbly/internal/app/warmupcontent"
	"github.com/warmbly/warmbly/internal/app/webhook"
	"github.com/warmbly/warmbly/internal/app/websitetracking"
	"github.com/warmbly/warmbly/internal/app/worker"
	"github.com/warmbly/warmbly/internal/app/worker_orchestrator"
	"github.com/warmbly/warmbly/internal/pkg/generation"

	"github.com/warmbly/warmbly/internal/infrastructure/encryptedkeys"
	"github.com/warmbly/warmbly/internal/infrastructure/pubsub"
	"github.com/warmbly/warmbly/internal/infrastructure/storage"
	"github.com/warmbly/warmbly/internal/models"
	"github.com/warmbly/warmbly/internal/notify"
	"github.com/warmbly/warmbly/internal/repository"
	"github.com/warmbly/warmbly/internal/tasks"
)

type Handler struct {
	AuthService    auth.AuthService
	TokenService   token.TokenService
	PasskeyService passkey.Service

	// Native-app social sign-in discovery (GET /auth/providers).
	ExternalAuthProviders models.ExternalAuthProviders

	// Deployment facts served by GET /auth/config so the login screen renders
	// what this backend can actually do instead of guessing. The sign-in
	// provider list is not here: it comes from the auth service, which is what
	// actually holds the configured flows.
	MailDelivers   bool
	PasskeysUsable bool
	MailTransport  string
	// MailTransportRef backs the admin mail diagnostics, which need Preflight
	// and so cannot go through the EmailNotificationService interface.
	MailTransportRef *notify.Transport
	// BootstrapService backs the first-run setup page.
	BootstrapService *bootstrap.Service
	UserService      user.UserService
	EmailService     email.EmailService
	CampaignService  campaign.CampaignService
	ContactService   contact.ContactService
	SegmentService   segment.Service
	FormService      form.Service
	SequenceService  sequence.SequenceService
	UniboxService    unibox.UniboxService

	FolderService   group.GroupService
	TagService      group.GroupService
	CategoryService group.GroupService

	TzService           tz.TzService
	SocketService       socket.SocketService
	TasksService        tasks.TasksService
	NotificationService notification.Service
	TwoFAService        twofa.Service

	// New services
	APIKeyService    apikey.APIKeyService
	AnalyticsService analytics.AnalyticsService
	AuditService     audit.AuditService
	RateLimitService ratelimit.RateLimitService

	// Subscription & billing
	SubscriptionService subscription.SubscriptionService
	StripeService       stripe.StripeService
	DiscountService     discount.DiscountService
	ReferralService     referral.Service

	// Trial & feature gates
	TrialService            trial.TrialService
	FeatureGateService      feature.FeatureGateService
	WorkerAssignmentService worker.WorkerAssignmentService

	// Organization & IAM
	OrganizationService organization.OrganizationService
	OrgRiskService      orgrisk.Service

	// CRM
	CRMService crm.CRMService

	// Teams
	TeamService team.TeamService

	// Email send & templates
	TemplateService  template.TemplateService
	EmailSendService emailsend.EmailSendService

	// Compose mailbox picker: scores the org's mailboxes for a recipient
	// (affinity, budget, auth health) and backs auto selection.
	ComposeService compose.Service

	// Admin
	AdminService         admin.AdminService
	AdminOutreachService adminoutreach.Service

	// Worker orchestration (SSH-driven lifecycle for admin-managed workers)
	WorkerOrchestrator *worker_orchestrator.Orchestrator
	WorkerRepo         repository.WorkerRepository
	CredentialsRepo    repository.CredentialsRepository
	ReleasesService    *releases.Service
	// UpdatesService backs the admin panel's update indicator and button.
	UpdatesService *updates.Service

	// Notifications
	EmailNotificationService notify.EmailNotificationService

	// Advanced outreach controls
	AdvancedService advanced.Service
	// UnsubscribeLinks verifies the signed tokens on recipient unsubscribe
	// links. Nil when the instance has no public API URL to mint them on.
	UnsubscribeLinks *unsublink.Signer

	// Website tracking snippet: settings and the page-view ingest path.
	WebsiteTrackingService websitetracking.Service

	// Pre-send email verification (control-plane SMTP RCPT probe / pluggable
	// paid backend). Drops hard-bouncing addresses before a worker sends.
	EmailVerifyService emailverifyapp.Service

	// Per-mailbox human sending behaviour: the ranges a mailbox rolls its
	// workday from, and the plan it rolled for today. Nil disables the
	// behaviour endpoints (the schedulers then run every mailbox on its fixed
	// cap and gap).
	BehaviorService behavior.Service

	// Warmup health
	WarmupService warmup.Service

	// Warmup routing rules — customer-defined preferences for premium-pool
	// partner selection (e.g. Gmail recipients from Google Workspace senders).
	WarmupRoutingRepo repository.WarmupRoutingRepository

	// Warmup content bank + offline AI generator (admin control/visibility).
	WarmupContentRepo    repository.WarmupContentRepository
	WarmupContentService warmupcontent.Service

	// AI writing assistant + credit ledger.
	CreditService    credits.CreditService
	WritingGenerator generation.WritingGenerator

	// AI provider layer (RunAgent tool-loop backend) + pluggable web search,
	// shared by the dashboard agent, research, automation AI nodes, and the
	// inbox agent. Nil when no LLM provider is configured.
	AIProvider generation.Provider
	AISearch   generation.SearchClient

	// AITools is the shared tool registry the dashboard agent and MCP server
	// run on. Handlers bound to the invoking user's permissions.
	AITools *aitools.Registry

	// AIAgentService orchestrates the dashboard agent (sessions, SSE runs,
	// approvals, per-iteration credits). Nil when no LLM provider is configured.
	AIAgentService aiagent.Service

	// ResearchService runs the AI contact-research agent (sync + batch).
	ResearchService research.Service

	// SkillsService manages org AI skills (playbooks) and injects them into AI
	// prompts.
	SkillsService skills.Service

	// MCPService manages org-connected MCP servers (external tools).
	MCPService mcp.Service

	// AIDraftRepo stores inbox-agent reply drafts awaiting human review (M10).
	// The draft is created in the consumer; these list/approve/discard handlers
	// read + resolve it. Nil disables the review endpoints.
	AIDraftRepo repository.AIDraftRepository

	// Seed inbox-placement testing.
	PlacementRepo    repository.PlacementRepository
	PlacementService placement.Service

	// Advisor: continuously-evaluated recommendations about deliverability,
	// mailbox config, warmup, campaign performance, copy, and list hygiene.
	// The repository is held alongside the service so a read can cheaply check
	// how stale the findings are before deciding to re-evaluate inline.
	AdvisorService    advisor.Service
	AdvisorRepository repository.AdvisorRepository

	// Customer-facing webhooks (subscribe → HMAC-signed delivery).
	WebhookService webhook.Service

	// Third-party integrations (Calendly, Cal.com, DMARC, Postmaster,
	// SNDS, Cloudflare, GoDaddy, Namecheap, Google Sheets).
	IntegrationService integration.Service
	ContactRepo        repository.ContactRepository

	// OAuth 2.1 authorization server (third-party app registration + the
	// authorization-code-with-PKCE flow + bearer-token validation).
	OAuthService *oauth.Service

	// Realtime publisher for handler paths that emit live dashboard events
	// directly (inbound meeting webhooks have no service layer of their own).
	// nil-safe: realtime is a nicety, not a requirement.
	StreamingPublisher *pubsub.StreamingPublisher

	// On-demand Google Sheets -> leads sync. Reuses the google_sheets OAuth
	// connection's token to read sheets and the contact import path to upsert.
	LeadSyncService leadsync.Service

	// Public websocket URL used by frontend clients
	WebsocketURI string

	// Object storage for user-uploaded artifacts (avatars, etc.).
	Storage storage.Store

	// Encrypted-DEK store. Served to workers over HTTPS at
	// /api/v1/internal/dek/:userID so workers don't need direct Postgres
	// access. Backend processes use Postgres directly; workers use the
	// HTTP-proxy implementation.
	EncryptedKeys encryptedkeys.Store

	// Worker messageId -> internal email map, served to workers over HTTPS at
	// /api/v1/internal/email-message-map for the same no-direct-Postgres reason
	// as EncryptedKeys. Backed by Postgres in the backend.
	EmailMessageMap repository.EmailMessageMapRepository

	// Mailbox sync state, read by the dashboard (GET /emails/:id/sync) and by
	// the worker's priority lane over /api/v1/internal/sync/own-conversation.
	EmailSyncState repository.EmailSyncStateRepository

	// Click-link store, served to the tracking service over HTTPS at
	// /api/v1/internal/tracked-links/:id (same no-direct-Postgres rule).
	TrackedLinks repository.TrackedLinkRepository

	// Direct repositories used by handlers that don't yet have a
	// service layer (avatars, etc.). Keep narrow and add a service
	// only when business logic accumulates.
	UserRepo                 repository.UserRepository
	OrgRepo                  repository.OrganizationRepository
	AttachmentRepo           repository.AttachmentRepository
	StorageBackendRepo       repository.StorageBackendRepository
	CloudCredentialRepo      repository.CloudCredentialRepository
	ProvisioningTemplateRepo repository.ProvisioningTemplateRepository
	ProvisioningJobRepo      repository.ProvisioningJobRepository
	ProvisioningPolicyRepo   repository.ProvisioningPolicyRepository

	// Danger zone (delayed deletions for orgs & user accounts)
	DangerZoneService dangerzone.Service

	// Workspace archives: export an organization to a portable file and import
	// one back, for moving between instances. Nil disables the endpoints.
	OrgTransferService orgtransfer.Service

	// PoolLinkService (cloud side) and CloudLinkService (self-hosted side) are nil-safe: routes answer 501.
	PoolLinkService  poollink.Service
	CloudLinkService cloudlink.Service

	// Device-code sign-in for the `warmbly` CLI. Nil-safe: routes answer 501.
	CLIAuthService cliauth.Service

	// Infrastructure liveness probes for the admin System Status page.
	// Wired in cmd/backend/main.go where the concrete clients live.
	SystemChecker *sysstatus.Checker

	// Operator visibility (admin panel, Instance section).
	//
	// InstanceRuntime carries the facts only boot knows (the resolved CORS
	// list, the WebAuthn RP, the OIDC redirect, the auth policy) so the
	// configuration page shows what the process actually derived. Nil is safe:
	// every resolver falls back to the environment.
	InstanceRuntime *instanceconfig.Runtime
	// InstanceChecks is the setup and health registry. Nil falls back to the
	// environment-only checks, so the page is never blank.
	InstanceChecks *instancecheck.Registry
	// InstanceSettings is the database-backed settings tier. It holds only
	// keys no environment variable owns.
	InstanceSettings instancesettings.Service
	// OpsNotifier delivers instance-wide operator alerts. Nil disables the
	// notification admin surface.
	OpsNotifier opsnotify.Notifier
}
