package example

import (
	"context"
	"errors"
	"mime/multipart"
	"strings"
	"time"
)

// FileUpload 文件上传实体
type FileUpload struct {
	ID        uint
	Name      string
	ClassId   int
	Url       string
	Tag       string
	Key       string
	CreatedAt time.Time
	UpdatedAt time.Time
}

// FileUploadSearchReq 文件搜索请求
type FileUploadSearchReq struct {
	Page     int
	PageSize int
	Keyword  string
	ClassId  int
}

// OssUploader OSS上传接口（与 pkg/upload.OSS 兼容）
type OssUploader interface {
	UploadFile(file *multipart.FileHeader) (string, string, error)
	DeleteFile(key string) error
}

// NilOssUploader 空OSS上传器（用于未配置OSS时）
type NilOssUploader struct{}

func (n *NilOssUploader) UploadFile(file *multipart.FileHeader) (string, string, error) {
	return "", "", errors.New("OSS未配置")
}

func (n *NilOssUploader) DeleteFile(key string) error {
	return errors.New("OSS未配置")
}

// FileUploadRepo 文件上传仓储接口
type FileUploadRepo interface {
	Create(ctx context.Context, file *FileUpload) error
	Update(ctx context.Context, file *FileUpload) error
	Delete(ctx context.Context, id uint) error
	FindByID(ctx context.Context, id uint) (*FileUpload, error)
	FindByKey(ctx context.Context, key string) (*FileUpload, error)
	List(ctx context.Context, req *FileUploadSearchReq) ([]*FileUpload, int64, error)
	BatchCreate(ctx context.Context, files []*FileUpload) error
}

// FileUploadUsecase 文件上传用例
type FileUploadUsecase struct {
	repo FileUploadRepo
	oss  OssUploader
}

// NewFileUploadUsecase 创建文件上传用例
func NewFileUploadUsecase(repo FileUploadRepo, oss OssUploader) *FileUploadUsecase {
	return &FileUploadUsecase{repo: repo, oss: oss}
}

// Upload 创建文件上传记录
func (uc *FileUploadUsecase) Upload(ctx context.Context, file *FileUpload) error {
	return uc.repo.Create(ctx, file)
}

// FindFile 查询文件记录
func (uc *FileUploadUsecase) FindFile(ctx context.Context, id uint) (*FileUpload, error) {
	return uc.repo.FindByID(ctx, id)
}

// DeleteFile 删除文件记录
func (uc *FileUploadUsecase) DeleteFile(ctx context.Context, id uint) error {
	file, err := uc.repo.FindByID(ctx, id)
	if err != nil {
		return err
	}

	// 删除OSS文件
	if uc.oss != nil && file.Key != "" {
		if err := uc.oss.DeleteFile(file.Key); err != nil {
			return errors.New("文件删除失败")
		}
	}

	return uc.repo.Delete(ctx, id)
}

// EditFileName 编辑文件名
func (uc *FileUploadUsecase) EditFileName(ctx context.Context, id uint, name string) error {
	file, err := uc.repo.FindByID(ctx, id)
	if err != nil {
		return err
	}
	file.Name = name
	return uc.repo.Update(ctx, file)
}

// GetFileRecordInfoList 分页获取文件列表
func (uc *FileUploadUsecase) GetFileRecordInfoList(ctx context.Context, req *FileUploadSearchReq) ([]*FileUpload, int64, error) {
	return uc.repo.List(ctx, req)
}

// UploadFile 上传文件
func (uc *FileUploadUsecase) UploadFile(ctx context.Context, header *multipart.FileHeader, noSave string, classId int) (*FileUpload, error) {
	if uc.oss == nil {
		return nil, errors.New("OSS未配置")
	}

	filePath, key, err := uc.oss.UploadFile(header)
	if err != nil {
		return nil, err
	}

	s := strings.Split(header.Filename, ".")
	file := &FileUpload{
		Url:     filePath,
		Name:    header.Filename,
		ClassId: classId,
		Tag:     s[len(s)-1],
		Key:     key,
	}

	if noSave == "0" {
		// 检查是否已存在相同key的记录
		existing, _ := uc.repo.FindByKey(ctx, key)
		if existing == nil {
			if err := uc.repo.Create(ctx, file); err != nil {
				return nil, err
			}
		}
	}

	return file, nil
}

// ImportURL 导入URL
func (uc *FileUploadUsecase) ImportURL(ctx context.Context, files []*FileUpload) error {
	return uc.repo.BatchCreate(ctx, files)
}
