package aws_service

import (
	"fmt"
	"io"
	"time"

	"github.com/UpmeshLTD/urus-aio/shipment/config"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/aws/aws-sdk-go/service/s3/s3manager"
)

const (
	folderImportParticipant = "import-participant"
)

type IAWSService interface {
	UploadShippingLabel(courierTrackingID string, stream io.Reader) (string, error)
	GetShippingLabelURL(objectKey string) (string, error)
}

type awsServiceImpl struct {
	client     *s3.S3
	cfg        config.Config
	bucket     string
	awsSession *session.Session
}

func NewAWSService(cfg config.Config) IAWSService {
	awsConfig := cfg.GetAwsConfig()
	sess := session.Must(session.NewSession(
		&aws.Config{
			Region: aws.String(awsConfig.Region),
		}))
	return &awsServiceImpl{
		cfg:        cfg,
		client:     s3.New(sess),
		awsSession: sess,
	}
}

func (s *awsServiceImpl) UploadShippingLabel(courierTrackingID string, stream io.Reader) (string, error) {
	filePath := fmt.Sprintf("%s/%s.pdf", s.cfg.GetAwsConfig().ShippingLabelFolder, courierTrackingID)

	uploader := s3manager.NewUploader(s.awsSession)
	_, err := uploader.Upload(&s3manager.UploadInput{
		Bucket: aws.String(s.cfg.GetAwsConfig().ShippingLabelBucket),
		Key:    aws.String(filePath),
		ACL:    aws.String("private"), // could be private if you want it to be access by only authorized users
		Body:   stream,
	})

	if err != nil {
		return "", err
	}
	return filePath, err
}

func (s *awsServiceImpl) GetShippingLabelURL(courierTrackingID string) (string, error) {
	ttl := time.Duration(s.cfg.GetAwsConfig().ShippingLabelPresignedTTL) * time.Minute
	objectKey := fmt.Sprintf("%s/%s.pdf", s.cfg.GetAwsConfig().ShippingLabelFolder, courierTrackingID)
	return s.getPreSignedURL(s.cfg.GetAwsConfig().ShippingLabelBucket, objectKey, ttl)
}

func (s *awsServiceImpl) getPreSignedURL(bucket, objectKey string, ttl time.Duration) (string, error) {
	req, _ := s.client.GetObjectRequest(&s3.GetObjectInput{
		Bucket:                     aws.String(bucket),
		Key:                        aws.String(objectKey),
		ResponseContentType:        aws.String("application/pdf"),
		ResponseContentDisposition: aws.String("inline"),
	})

	url, err := req.Presign(ttl)
	if err != nil {
		return "", fmt.Errorf("failed to presign GetObjectRequest for key %q: %v", objectKey, err)
	}

	return url, nil
}
