package storage

import (
	"context"
	"fmt"
	"io"
	"net/url"
	"time"

	"github.com/google/uuid"
	"github.com/minio/minio-go/v7"
)

type Client struct {
	mc     *minio.Client
	bucket string
}

func NewClient(mc *minio.Client, bucket string) *Client {
	return &Client{mc: mc, bucket: bucket}
}

func (c *Client) EnsureBucket(ctx context.Context) error {
	exists, err := c.mc.BucketExists(ctx, c.bucket)
	if err != nil {
		return err
	}
	if !exists {
		return c.mc.MakeBucket(ctx, c.bucket, minio.MakeBucketOptions{})
	}
	return nil
}

func (c *Client) Put(ctx context.Context, objectKey string, reader io.Reader, size int64, contentType string) error {
	_, err := c.mc.PutObject(ctx, c.bucket, objectKey, reader, size, minio.PutObjectOptions{
		ContentType: contentType,
	})
	return err
}

func (c *Client) Get(ctx context.Context, objectKey string) (*minio.Object, error) {
	return c.mc.GetObject(ctx, c.bucket, objectKey, minio.GetObjectOptions{})
}

func (c *Client) Delete(ctx context.Context, objectKey string) error {
	return c.mc.RemoveObject(ctx, c.bucket, objectKey, minio.RemoveObjectOptions{})
}

func (c *Client) PresignedGet(ctx context.Context, objectKey string, expiry time.Duration) (*url.URL, error) {
	return c.mc.PresignedGetObject(ctx, c.bucket, objectKey, expiry, nil)
}

func MessageObjectKey(userID, messageID, filename string) string {
	return fmt.Sprintf("%s/messages/%s/%s/%s", userID, messageID, uuid.NewString(), filename)
}

func DraftObjectKey(userID, draftID, filename string) string {
	return fmt.Sprintf("%s/drafts/%s/%s/%s", userID, draftID, uuid.NewString(), filename)
}
