package model

import (
	"context"
	"gorm.io/gorm"
	"gxt-file-server/app/errors"
	"gxt-file-server/app/model/entity"
	"gxt-file-server/app/schema"
	"time"
)

// NewFileChunk 创建demo存储实例
func NewFileChunk(db *gorm.DB) *FileChunk {
	return &FileChunk{db}
}

// FileChunk demo存储
type FileChunk struct {
	db *gorm.DB
}

func (a *FileChunk) getQueryOption(opts ...schema.FileChunkQueryOptions) schema.FileChunkQueryOptions {
	var opt schema.FileChunkQueryOptions
	if len(opts) > 0 {
		opt = opts[0]
	}
	return opt
}

// Query 查询数据
func (a *FileChunk) Query(ctx context.Context, params schema.FileChunkQueryParam, opts ...schema.FileChunkQueryOptions) (*schema.FileChunkQueryResult, error) {
	db := entity.GetFileChunkDB(ctx, a.db)
	if v := params.Hash; v != "" {
		db = db.Where("hash = ?", v)
	}
	if v := params.Current; v > 0 {
		db = db.Where("current = ?", v)
	}
	if v := params.IsClear; v {
		//精确到秒 已备定时扫表的定时任务为秒/分钟
		timeNowString := time.Now().Format("2006-01-02 15:04:05")
		db = db.Where("past_time < ?", timeNowString)
	}
	//按照块的顺序排序 不可变更 ！！！ guo
	db = db.Order("current ASC")

	opt := a.getQueryOption(opts...)
	var list entity.FileChunks
	pr, err := WrapPageQuery(ctx, db, opt.PageParam, &list)
	if err != nil {
		return nil, errors.ErrDBServerInternalError
	}
	qr := &schema.FileChunkQueryResult{
		PageResult: pr,
		Data:       list.ToSchemaFileChunks(),
	}

	return qr, nil
}

// Get 查询指定数据
func (a *FileChunk) Get(ctx context.Context, recordID string, opts ...schema.FileChunkQueryOptions) (*schema.FileChunk, error) {
	db := entity.GetFileChunkDB(ctx, a.db).Where("record_id=?", recordID)
	var item entity.FileChunk
	ok, err := FindOne(ctx, db, &item)
	if err != nil {
		return nil, errors.ErrDBServerInternalError
	} else if !ok {
		return nil, nil
	}

	return item.ToSchemaFileChunk(), nil
}

// Create 创建数据
func (a *FileChunk) Create(ctx context.Context, item schema.FileChunk) error {
	demo := entity.SchemaFileChunk(item).ToFileChunk()
	result := entity.GetFileChunkDB(ctx, a.db).Create(demo)
	if err := result.Error; err != nil {
		return errors.ErrDBServerInternalError
	}
	return nil
}

// Update 更新数据
func (a *FileChunk) Update(ctx context.Context, recordID string, item schema.FileChunk) error {
	demo := entity.SchemaFileChunk(item).ToFileChunk()
	result := entity.GetFileChunkDB(ctx, a.db).Where("record_id=?", recordID).Omit("record_id", "creator").Updates(demo)
	if err := result.Error; err != nil {
		return errors.ErrDBServerInternalError
	}
	return nil
}

// Delete 真实删除数据
func (a *FileChunk) Delete(ctx context.Context, recordID string) error {
	result := entity.GetFileChunkDB(ctx, a.db).Where("record_id=?", recordID).Unscoped().Delete(entity.FileChunk{})
	if err := result.Error; err != nil {
		return errors.ErrDBServerInternalError
	}
	return nil
}

// DeleteHash 根据HASH真实删除数据
func (a *FileChunk) DeleteHash(ctx context.Context, hash string) error {
	result := entity.GetFileChunkDB(ctx, a.db).Where("hash=?", hash).Unscoped().Delete(entity.FileChunk{})
	if err := result.Error; err != nil {
		return errors.ErrDBServerInternalError
	}
	return nil
}

// UpdateStatus 更新状态
func (a *FileChunk) UpdateStatus(ctx context.Context, recordID string, status int) error {
	result := entity.GetFileChunkDB(ctx, a.db).Where("record_id=?", recordID).Update("status", status)
	if err := result.Error; err != nil {
		return errors.ErrDBServerInternalError
	}
	return nil
}
