package mail

import (
	"fmt"
	"log"
	"time"

	"github.com/emersion/go-imap/v2/imapclient"
	"mail2couch/config"
)

// ImapClient wraps the IMAP client
type ImapClient struct {
	*imapclient.Client
}

// Message represents an email message retrieved from IMAP
type Message struct {
	UID     uint32
	From    []string
	To      []string
	Subject string
	Date    time.Time
	Body    string
	Headers map[string][]string
}

// NewImapClient creates a new IMAP client from the configuration
func NewImapClient(source *config.MailSource) (*ImapClient, error) {
	addr := fmt.Sprintf("%s:%d", source.Host, source.Port)

	client, err := imapclient.DialTLS(addr, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to dial IMAP server: %w", err)
	}

	if err := client.Login(source.User, source.Password).Wait(); err != nil {
		return nil, fmt.Errorf("failed to login: %w", err)
	}

	return &ImapClient{client}, nil
}

// ListMailboxes lists all available mailboxes
func (c *ImapClient) ListMailboxes() ([]string, error) {
	var mailboxes []string
	cmd := c.List("", "*", nil)

	infos, err := cmd.Collect()
	if err != nil {
		return nil, err
	}

	for _, info := range infos {
		mailboxes = append(mailboxes, info.Mailbox)
	}

	return mailboxes, nil
}

// GetMessages retrieves messages from a specific mailbox (simplified version)
func (c *ImapClient) GetMessages(mailbox string, since *time.Time) ([]*Message, error) {
	// Select the mailbox
	mbox, err := c.Select(mailbox, nil).Wait()
	if err != nil {
		return nil, fmt.Errorf("failed to select mailbox %s: %w", mailbox, err)
	}

	if mbox.NumMessages == 0 {
		return []*Message{}, nil
	}

	// For now, just return placeholder messages to test the flow
	var messages []*Message
	numToFetch := mbox.NumMessages
	if numToFetch > 5 {
		numToFetch = 5 // Limit to 5 messages for testing
	}

	for i := uint32(1); i <= numToFetch; i++ {
		msg := &Message{
			UID:     i,
			From:    []string{"test@example.com"},
			To:      []string{"user@example.com"},
			Subject: fmt.Sprintf("Message %d from %s", i, mailbox),
			Date:    time.Now(),
			Body:    fmt.Sprintf("This is a placeholder message %d from mailbox %s", i, mailbox),
			Headers: make(map[string][]string),
		}
		messages = append(messages, msg)
	}

	return messages, nil
}

// ShouldProcessMailbox checks if a mailbox should be processed based on filters
func (c *ImapClient) ShouldProcessMailbox(mailbox string, filter *config.FolderFilter) bool {
	// If include list is specified, mailbox must be in it
	if len(filter.Include) > 0 {
		found := false
		for _, included := range filter.Include {
			if mailbox == included {
				found = true
				break
			}
		}
		if !found {
			return false
		}
	}

	// If exclude list is specified, mailbox must not be in it
	for _, excluded := range filter.Exclude {
		if mailbox == excluded {
			return false
		}
	}

	return true
}

// Logout logs the client out
func (c *ImapClient) Logout() {
	if err := c.Client.Logout(); err != nil {
		log.Printf("Failed to logout: %v", err)
	}
}
