package main

import (
	"flag"
	"os"
	"os/signal"
	"syscall"
	"time"

	"paraclub-ai-mailer/config"
	"paraclub-ai-mailer/internal/ai"
	"paraclub-ai-mailer/internal/fetcher"
	"paraclub-ai-mailer/internal/imap"
	"paraclub-ai-mailer/internal/logger"

	"github.com/sirupsen/logrus"
)

func main() {
	configPath := flag.String("config", "config.yaml", "Path to configuration file")
	flag.Parse()

	// Load configuration
	logger.Debug("Loading configuration from:", *configPath)
	cfg, err := config.Load(*configPath)
	if err != nil {
		logger.WithError(err).Error("Failed to load configuration")
		panic(err)
	}
	logger.WithFields(logrus.Fields{
		"logLevel": cfg.Logging.Level,
		"logFile":  cfg.Logging.FilePath,
	}).Debug("Configuration loaded successfully")

	// Initialize logger
	if err := logger.Init(cfg.Logging.Level, cfg.Logging.FilePath); err != nil {
		logger.WithError(err).Error("Failed to initialize logger")
		panic(err)
	}
	logger.Debug("Logger initialized successfully")

	// Initialize components
	logger.WithFields(logrus.Fields{
		"server":    cfg.IMAP.Server,
		"port":      cfg.IMAP.Port,
		"username":  cfg.IMAP.Username,
		"mailboxIn": cfg.IMAP.MailboxIn,
	}).Debug("Initializing IMAP client")

	imapClient, err := imap.New(cfg.IMAP)
	if err != nil {
		logger.WithError(err).Error("Failed to initialize IMAP client")
		os.Exit(1)
	}
	defer imapClient.Close()

	fetcher := fetcher.New()
	aiProcessor := ai.New(cfg.AI)
	logger.Debug("All components initialized successfully")

	// Setup signal handling for graceful shutdown
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	done := make(chan bool, 1)
	logger.Debug("Signal handlers configured")

	// Start processing loop
	logger.WithField("pollingInterval", cfg.Polling.Interval).Info("Starting email processing loop")
	go func() {
		ticker := time.NewTicker(cfg.Polling.Interval)
		defer ticker.Stop()
		for {
			select {
			case <-done:
				logger.Debug("Received shutdown signal in processing loop")
				return
			case <-ticker.C:
				logger.Debug("Processing tick started")
				processEmails(imapClient, fetcher, aiProcessor, cfg)
				logger.Debug("Processing tick completed")
			}
		}
	}()

	// Wait for shutdown signal
	sig := <-sigChan
	logger.WithField("signal", sig.String()).Info("Received shutdown signal")
	done <- true
	logger.Info("Application shutdown complete")
}

func processEmails(imapClient *imap.IMAPClient, fetcher *fetcher.Fetcher, aiProcessor *ai.AI, cfg *config.Config) {
	logger.Debug("Starting email processing cycle")

	// Fetch unprocessed emails
	emails, err := imapClient.FetchUnprocessedEmails()
	if err != nil {
		logger.WithError(err).Error("Failed to fetch emails")
		return
	}

	logger.WithField("emailCount", len(emails)).Debug("Fetched unprocessed emails")

	if len(emails) == 0 {
		logger.Debug("No new emails to process")
		return
	}

	// Fetch context from configured URLs
	logger.WithField("urlCount", len(cfg.Context.URLs)).Debug("Fetching context from configured URLs")
	contextContent, err := fetcher.FetchAllURLs(cfg.Context.URLs)
	if err != nil {
		logger.WithError(err).Error("Failed to fetch context content")
		return
	}
	logger.WithField("contextCount", len(contextContent)).Debug("Successfully fetched context content")

	// Process each email
	var processedCount, errorCount int
	for _, email := range emails {
		logger.WithFields(logrus.Fields{
			"subject":   email.Subject,
			"from":      email.From,
			"messageId": email.ID,
		}).Info("Processing email")

		// Generate AI response
		response, err := aiProcessor.GenerateReply(email.Body, contextContent)
		if err != nil {
			logger.WithFields(logrus.Fields{
				"subject": email.Subject,
				"error":   err,
			}).Error("Failed to generate reply")
			errorCount++
			continue
		}
		logger.WithField("responseLength", len(response)).Debug("Generated AI response")

		// Save as draft
		if err := imapClient.SaveDraft(email, response); err != nil {
			logger.WithFields(logrus.Fields{
				"subject": email.Subject,
				"error":   err,
			}).Error("Failed to save draft")
			errorCount++
			continue
		}
		logger.Debug("Saved response as draft")

		// Mark email as processed
		if err := imapClient.MarkAsProcessed(email); err != nil {
			logger.WithFields(logrus.Fields{
				"subject": email.Subject,
				"error":   err,
			}).Error("Failed to mark email as processed")
			errorCount++
			continue
		}

		processedCount++
		logger.WithFields(logrus.Fields{
			"subject": email.Subject,
			"from":    email.From,
		}).Info("Successfully processed email")
	}

	logger.WithFields(logrus.Fields{
		"totalEmails": len(emails),
		"processed":   processedCount,
		"errors":      errorCount,
	}).Info("Completed email processing cycle")
}
