package ai

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"path"
	"strings"
	"time"

	"github.com/jackc/pgx/v5/pgxpool"

	"github.com/ultisuite/ulti-backend/internal/nextcloud"
)

type ChatStore struct {
	nc *nextcloud.Client
	db *pgxpool.Pool
}

func NewChatStore(nc *nextcloud.Client, db *pgxpool.Pool) *ChatStore {
	return &ChatStore{nc: nc, db: db}
}

func (s *ChatStore) Sync(ctx context.Context, userEmail string, record ChatRecord) error {
	if s == nil || s.nc == nil {
		return fmt.Errorf("nextcloud unavailable")
	}
	policy, _ := LoadAssistantPolicy(ctx, s.db)
	basePath := policy.ChatNCPath
	if strings.TrimSpace(basePath) == "" {
		basePath = nextcloud.DefaultChatNCBasePath
	}
	if strings.TrimSpace(record.ID) == "" {
		return fmt.Errorf("chat id required")
	}
	if record.UpdatedAt.IsZero() {
		record.UpdatedAt = time.Now().UTC()
	}
	if record.CreatedAt.IsZero() {
		record.CreatedAt = record.UpdatedAt
	}
	if strings.TrimSpace(record.Source) == "" {
		record.Source = "openwebui"
	}

	userID := nextcloud.UserIDFromClaims(userEmail, "")
	sidecarPath := nextcloud.ChatSidecarPath(basePath, record.ID)
	dir := path.Dir(sidecarPath)
	if dir != "/" && dir != "." {
		_ = s.nc.CreateFolder(ctx, userID, dir)
	}

	payload, err := json.MarshalIndent(record, "", "  ")
	if err != nil {
		return err
	}
	return s.nc.Upload(ctx, userID, sidecarPath, strings.NewReader(string(payload)), "application/json")
}

func (s *ChatStore) Get(ctx context.Context, userEmail, chatID string) (ChatRecord, error) {
	if s == nil || s.nc == nil {
		return ChatRecord{}, fmt.Errorf("nextcloud unavailable")
	}
	policy, _ := LoadAssistantPolicy(ctx, s.db)
	basePath := policy.ChatNCPath
	if strings.TrimSpace(basePath) == "" {
		basePath = nextcloud.DefaultChatNCBasePath
	}
	userID := nextcloud.UserIDFromClaims(userEmail, "")
	sidecarPath := nextcloud.ChatSidecarPath(basePath, chatID)
	body, _, err := s.nc.Download(ctx, userID, sidecarPath)
	if err != nil {
		return ChatRecord{}, err
	}
	defer body.Close()
	raw, err := io.ReadAll(io.LimitReader(body, 8<<20))
	if err != nil {
		return ChatRecord{}, err
	}
	var record ChatRecord
	if err := json.Unmarshal(raw, &record); err != nil {
		return ChatRecord{}, err
	}
	return record, nil
}

func (s *ChatStore) Delete(ctx context.Context, userEmail, chatID string) error {
	if s == nil || s.nc == nil {
		return fmt.Errorf("nextcloud unavailable")
	}
	policy, _ := LoadAssistantPolicy(ctx, s.db)
	basePath := policy.ChatNCPath
	if strings.TrimSpace(basePath) == "" {
		basePath = nextcloud.DefaultChatNCBasePath
	}
	userID := nextcloud.UserIDFromClaims(userEmail, "")
	sidecarPath := nextcloud.ChatSidecarPath(basePath, chatID)
	return s.nc.Delete(ctx, userID, sidecarPath)
}
