package nextcloud

import (
	"context"
	"errors"
	"fmt"

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

	"github.com/ultisuite/ulti-backend/internal/mail/credentials"
)

var ErrDAVCredentialsMissing = errors.New("nextcloud dav credentials missing")

type DAVCredentialStore struct {
	db  *pgxpool.Pool
	enc *credentials.Manager
}

func NewDAVCredentialStore(db *pgxpool.Pool, enc *credentials.Manager) *DAVCredentialStore {
	if db == nil || enc == nil {
		return nil
	}
	return &DAVCredentialStore{db: db, enc: enc}
}

func (s *DAVCredentialStore) GetToken(ctx context.Context, ncUserID string) (string, error) {
	if s == nil {
		return "", ErrDAVCredentialsMissing
	}
	var blob []byte
	err := s.db.QueryRow(ctx, `
		SELECT dav_token FROM nextcloud_dav_credentials WHERE nc_user_id = $1
	`, ncUserID).Scan(&blob)
	if errors.Is(err, pgx.ErrNoRows) {
		return "", ErrDAVCredentialsMissing
	}
	if err != nil {
		return "", err
	}
	_, token, err := s.enc.Decrypt(blob)
	return token, err
}

func (s *DAVCredentialStore) SaveToken(ctx context.Context, ncUserID, token string) error {
	if s == nil {
		return fmt.Errorf("nextcloud dav credential store unavailable")
	}
	blob, err := s.enc.Encrypt(ncUserID, token)
	if err != nil {
		return err
	}
	_, err = s.db.Exec(ctx, `
		INSERT INTO nextcloud_dav_credentials (nc_user_id, dav_token, updated_at)
		VALUES ($1, $2, NOW())
		ON CONFLICT (nc_user_id) DO UPDATE
		SET dav_token = EXCLUDED.dav_token, updated_at = NOW()
	`, ncUserID, blob)
	return err
}

func (s *DAVCredentialStore) DeleteToken(ctx context.Context, ncUserID string) error {
	if s == nil {
		return nil
	}
	_, err := s.db.Exec(ctx, `DELETE FROM nextcloud_dav_credentials WHERE nc_user_id = $1`, ncUserID)
	return err
}
