package services

import (
	"context"
	"encoding/json"
	"fmt"
	"os"
	"time"

	"github.com/appwrite/sdk-for-go/client"
	"github.com/appwrite/sdk-for-go/databases"
)

type AppwriteConfig struct {
	Endpoint     string `json:"endpoint"`
	ProjectID    string `json:"projectId"`
	APIKey       string `json:"apiKey"`
	DatabaseID   string `json:"databaseId"`
	CollectionID string `json:"collectionId"`
}

type AppwriteService struct {
	credentialsService *CredentialsService
}

func NewAppwriteService(creds *CredentialsService) *AppwriteService {
	return &AppwriteService{
		credentialsService: creds,
	}
}

// PushMessage pushes a message to Appwrite Database for Realtime sync
func (s *AppwriteService) PushMessage(ctx context.Context, msgID, convoID, senderID, content string) error {
	config, err := s.getConfig(ctx)
	if err != nil {
		return fmt.Errorf("appwrite config error: %w", err)
	}

	if config.Endpoint == "" || config.ProjectID == "" {
		return fmt.Errorf("appwrite not configured")
	}

	// Initialize Client
	// sdk-for-go v0.16.x uses direct field assignment or AddHeader for config
	cl := client.New()
	cl.Endpoint = config.Endpoint
	cl.AddHeader("X-Appwrite-Project", config.ProjectID)
	cl.AddHeader("X-Appwrite-Key", config.APIKey)

	db := databases.New(cl)

	// Create Document
	_, err = db.CreateDocument(
		config.DatabaseID,
		config.CollectionID,
		msgID,
		map[string]interface{}{
			"conversation_id": convoID,
			"sender_id":       senderID,
			"content":         content,
			"timestamp":       time.Now().Format(time.RFC3339),
		},
		db.WithCreateDocumentPermissions([]string{}), // Optional permissions
	)
	if err != nil {
		return fmt.Errorf("failed to push to appwrite: %w", err)
	}

	return nil
}

func (s *AppwriteService) getConfig(ctx context.Context) (*AppwriteConfig, error) {
	// Try DB first
	payload, err := s.credentialsService.GetDecryptedKey(ctx, "appwrite")
	if err == nil && payload != "" {
		var cfg AppwriteConfig
		if err := json.Unmarshal([]byte(payload), &cfg); err == nil {
			return &cfg, nil
		}
	}

	// Fallback to Env
	return &AppwriteConfig{
		Endpoint:     os.Getenv("APPWRITE_ENDPOINT"),
		ProjectID:    os.Getenv("APPWRITE_PROJECT_ID"),
		APIKey:       os.Getenv("APPWRITE_API_KEY"),
		DatabaseID:   os.Getenv("APPWRITE_DATABASE_ID"),
		CollectionID: "messages", // Default if not set
	}, nil
}
