// Package connector_mail defines the provider-neutral mail effect seam used
// by Integration. It owns no OAuth state, HTTP grammar, durable queue, retry
// policy, provider recipe, or CRM completion behavior.
package connector_mail

import (
	"context"
	"errors"
	"time"
)

var ErrInvalidInput = errors.New("connected mail provider input is invalid")

type Message struct {
	FromAddress string
	ToAddresses []string
	Subject     string
	TextBody    string
}

// MessageV2 adds recipient classes and an optional HTML alternative without
// changing the released Message shape used by existing provider consumers.
type MessageV2 struct {
	Message      Message
	CcAddresses  []string
	BccAddresses []string
	HTMLBody     string
}

type Attachment struct {
	FileName    string
	ContentType string
	Data        []byte
}

// MessageV3 adds fully verified attachment bytes. Integration must load every
// intent-bound attachment before crossing this provider seam.
type MessageV3 struct {
	MessageV2
	Attachments []Attachment
}

type DispatchResult struct {
	RemoteMessageID string
	ResponseStatus  int
}

type ProviderErrorKind string

const (
	// ProviderNotDispatched proves no provider transaction began. A durable
	// owner may retry after its local dependency or deadline recovers.
	ProviderNotDispatched ProviderErrorKind = "not_dispatched"
	ProviderRejected      ProviderErrorKind = "rejected"
	ProviderAuthorization ProviderErrorKind = "authorization"
	// ProviderUncertain means provider acceptance may have occurred. Callers
	// must terminate or repair the effect rather than blindly send again.
	ProviderUncertain ProviderErrorKind = "uncertain"
)

// ProviderError is deliberately closed and contains no wrapped transport
// cause, provider response, header, access token, or message content.
type ProviderError struct {
	Kind ProviderErrorKind
}

func (failure *ProviderError) Error() string { return "connected mail provider failed" }

// Provider builds provider and MIME syntax inside Dispatch. Dispatch performs
// at most one provider transaction and never retries or follows redirects.
// The durable caller resolves authorization, throttle reservation, and token
// generation before crossing this seam. EffectTerminationBound has the same
// cancellation contract as connected OAuth effects.
type Provider interface {
	EffectTerminationBound() time.Duration
	Dispatch(context.Context, string, Message) (DispatchResult, error)
}

// ProviderV2 is the additive delivery seam for MailDeliveryV2. A worker must
// fail closed when a V2 intent resolves to a provider that implements only V1.
type ProviderV2 interface {
	Provider
	DispatchV2(context.Context, string, MessageV2) (DispatchResult, error)
}

type ProviderV3 interface {
	ProviderV2
	DispatchV3(context.Context, string, MessageV3) (DispatchResult, error)
}
