package controllers

import (
	"fmt"
	"io"

	"github.com/gogf/gf/v2/net/ghttp"
	"yx-dataset-server/app/bll"
	"yx-dataset-server/app/errors"
	"yx-dataset-server/app/schema"
	"yx-dataset-server/library/gplus"
)

type DatasetFile struct {
	DatasetFileBll bll.IDatasetFile
}

func NewDatasetFile(bDatasetFile bll.IDatasetFile) *DatasetFile {
	return &DatasetFile{
		DatasetFileBll: bDatasetFile,
	}
}

// Query 查询数据
func (a *DatasetFile) Query(r *ghttp.Request) {
	switch r.Get("q").String() {
	case "page":
		a.QueryPage(r)
	case "list":
		a.QueryList(r)
	default:
		gplus.ResError(r, errors.ErrUnknownQuery)
	}
}

// QueryPage 查询分页数据
// @Tags
// @Summary 查询分页数据
// @Param Authorization header string false "Bearer 用户令牌"
// @Param current query int true "分页索引" 1
// @Param pageSize query int true "分页大小" 10
// @Success 200 []schema.DatasetFile "查询结果：{list:列表数据,pagination:{current:页索引,pageSize:页大小,total:总数量}}"
// @Failure 400 schema.HTTPError "{error:{code:0,message:未知的查询类型}}"
// @Failure 401 schema.HTTPError "{error:{code:0,message:未授权}}"
// @Failure 500 schema.HTTPError "{error:{code:0,message:服务器错误}}"
// @Router GET /web/v1/dataset_files?q=page
func (a *DatasetFile) QueryPage(r *ghttp.Request) {
	ctx := gplus.NewContext(r)
	var params schema.DatasetFileQueryParam
	params.DatasetId = r.Get("dataset_id").String()
	result, err := a.DatasetFileBll.Query(ctx, params, schema.DatasetFileQueryOptions{
		PageParam: &schema.PaginationParam{
			PageIndex: gplus.GetPageIndex(r),
			PageSize:  gplus.GetPageSize(r),
		},
	})
	if err != nil {
		gplus.ResError(r, err)
	}
	ResPage(r, result.Data, result.PageResult)
}

// QueryList 查询列表数据
// @Tags
// @Summary 查询列表数据
// @Param Authorization header string false "Bearer 用户令牌"
// @Success 200 []schema.DatasetFile "查询结果：{list:列表数据}"
// @Failure 400 schema.HTTPError "{error:{code:0,message:未知的查询类型}}"
// @Failure 401 schema.HTTPError "{error:{code:0,message:未授权}}"
// @Failure 500 schema.HTTPError "{error:{code:0,message:服务器错误}}"
// @Router GET /web/v1/dataset_files?q=list
func (a *DatasetFile) QueryList(r *ghttp.Request) {
	ctx := gplus.NewContext(r)
	var params schema.DatasetFileQueryParam
	params.DatasetId = r.Get("dataset_id").String()
	result, err := a.DatasetFileBll.Query(ctx, params)
	if err != nil {
		gplus.ResError(r, err)
	}
	ResSuccess(r, result.Data)
}

// Get 获取数据
// @Summary 获取数据
// @Param id path string true "记录ID"
// @Success 200  schema.DatasetFile
// @Failure 400  schema.HTTPError "{error:{code:0,message:无效的请求参数}}"
// @Failure 401  schema.HTTPError "{error:{code:0,message:未授权}}"
// @Failure 500  schema.HTTPError "{error:{code:0,message:服务器错误}}"
// @Router  /web/v1/dataset_file/{id}
func (a *DatasetFile) Get(r *ghttp.Request) {
	ctx := gplus.NewContext(r)
	result, err := a.DatasetFileBll.Get(ctx, r.Get("id").String())
	if err != nil {
		gplus.ResError(r, err)
	}
	ResSuccess(r, result)
}

// Create 创建数据
// @Tags API-DatasetFile
// @Summary 创建数据
// @Param body schema.DatasetFile true "提交的数据"
// @Success 200  schema.DatasetFile
// @Failure 400  schema.HTTPError "{error:{code:0,message:无效的请求参数}}"
// @Failure 401  schema.HTTPError "{error:{code:0,message:未授权}}"
// @Failure 500  schema.HTTPError "{error:{code:0,message:服务器错误}}"
// @Router /web/v1/dataset_files/ [post]
func (a *DatasetFile) Create(r *ghttp.Request) {
	var data schema.DatasetFile
	if err := gplus.ParseJson(r, &data); err != nil {
		gplus.ResError(r, err)
	}

	ctx := gplus.NewContext(r)
	err := a.DatasetFileBll.Create(ctx, data)
	if err != nil {
		gplus.ResError(r, err)
	}
	ResSuccess(r, nil)
}

func (a *DatasetFile) BatchCreate(r *ghttp.Request) {
	var data schema.DatasetFiles
	if err := gplus.ParseJson(r, &data); err != nil {
		gplus.ResError(r, err)
	}

	ctx := gplus.NewContext(r)
	err := a.DatasetFileBll.BatchCreate(ctx, data)
	if err != nil {
		gplus.ResError(r, err)
	}
	ResSuccess(r, nil)
}

// Update 更新数据
// @Summary 更新数据
// @Param body schema.DatasetFile true "更新数据"
// @Success 200  schema.DatasetFile
// @Failure 400  schema.HTTPError "{error:{code:0,message:无效的请求参数}}"
// @Failure 401  schema.HTTPError "{error:{code:0,message:未授权}}"
// @Failure 500  schema.HTTPError "{error:{code:0,message:服务器错误}}"
// @Router  /web/v1/dataset_files/{id}
func (a *DatasetFile) Update(r *ghttp.Request) {
	var data schema.DatasetFile
	if err := gplus.ParseJson(r, &data); err != nil {
		gplus.ResError(r, err)
	}
	ctx := gplus.NewContext(r)
	err := a.DatasetFileBll.Update(ctx, r.Get("id").String(), data)
	if err != nil {
		gplus.ResError(r, err)
	}
	ResSuccess(r, nil)
}

// Delete 删除数据
// @Summary 删除数据
// @Param id path string true "记录ID"
// @Success 200  schema.HTTPStatus "{status:OK}"
// @Failure 400  schema.HTTPError "{error:{code:0,message:无效的请求参数}}"
// @Failure 401  schema.HTTPError "{error:{code:0,message:未授权}}"
// @Failure 500  schema.HTTPError "{error:{code:0,message:服务器错误}}"
// @Router  /web/v1/dataset_file/{id}
func (a *DatasetFile) Delete(r *ghttp.Request) {
	ctx := gplus.NewContext(r)
	err := a.DatasetFileBll.Delete(ctx, r.Get("id").String())
	if err != nil {
		gplus.ResError(r, err)
	}
	ResSuccess(r, nil)
}

func (a *DatasetFile) BatchDelete(r *ghttp.Request) {
	var Ids schema.DeleteIds
	if err := gplus.ParseJson(r, &Ids); err != nil {
		gplus.ResError(r, err)
	}

	ctx := gplus.NewContext(r)
	err := a.DatasetFileBll.BatchDelete(ctx, Ids.Ids)
	if err != nil {
		gplus.ResError(r, err)
	}
	ResSuccess(r, nil)
}

func (a *DatasetFile) Enabled(r *ghttp.Request) {
	ctx := gplus.NewContext(r)
	err := a.DatasetFileBll.UpdateEnabled(ctx, r.Get("id").String(), true)
	if err != nil {
		gplus.ResError(r, err)
	}
	ResSuccess(r, nil)
}

func (a *DatasetFile) Disabled(r *ghttp.Request) {
	ctx := gplus.NewContext(r)
	err := a.DatasetFileBll.UpdateEnabled(ctx, r.Get("id").String(), false)
	if err != nil {
		gplus.ResError(r, err)
	}
	ResSuccess(r, nil)
}

// CreateV2 上传本地文件（V2版本，直接上传到RagFlow，不再上传Minio）
// @Summary 上传本地文件到知识库（V2）
// @Description 接收文件上传，直接上传到RagFlow，不再上传Minio
// @Param Authorization header string false "Bearer 用户令牌"
// @Param file formData file true "文件"
// @Param dataset_id formData string true "知识库ID"
// @Success 200 schema.HTTPStatus "{status:OK}"
// @Failure 400 schema.HTTPError "{error:{code:0,message:无效的请求参数}}"
// @Failure 401 schema.HTTPError "{error:{code:0,message:未授权}}"
// @Failure 500 schema.HTTPError "{error:{code:0,message:服务器错误}}"
// @Router POST /web/v1/dataset_files/upload
func (a *DatasetFile) CreateV2(r *ghttp.Request) {
	ctx := gplus.NewContext(r)

	datasetId := r.Get("dataset_id").String()
	if datasetId == "" {
		gplus.ResError(r, errors.New400Response("dataset_id 不能为空"))
		return
	}

	file, header, err := r.Request.FormFile("file")
	if err != nil {
		gplus.ResError(r, errors.New400Response("请选择要上传的文件"))
		return
	}
	defer file.Close()

	// 直接读入内存后交给 BLL，避免落盘临时文件
	fileData, err := io.ReadAll(file)
	if err != nil {
		gplus.ResError(r, errors.New400Response("读取文件内容失败"))
		return
	}

	if err := a.DatasetFileBll.CreateV2(ctx, schema.UpdateFileParam{
		FileName:  header.Filename,
		FileData:  fileData,
		FileSize:  header.Size,
		DatasetId: datasetId,
		CreatorId: gplus.GetUserId(r),
	}); err != nil {
		gplus.ResError(r, err)
		return
	}

	ResSuccess(r, nil)
}

// BatchCreate2 批量上传多个文件到知识库（multipart form-data, 字段名 files）
// @Summary 批量上传文件到知识库
// @Param Authorization header string false "Bearer 用户令牌"
// @Param files formData file true "多文件，表单字段名为 files"
// @Param dataset_id formData string true "知识库ID"
// @Success 200 schema.HTTPStatus "{status:OK}"
// @Failure 400 schema.HTTPError "{error:{code:0,message:无效的请求参数}}"
// @Router POST /web/v1/dataset_files/batch2
func (a *DatasetFile) BatchCreateV2(r *ghttp.Request) {
	ctx := gplus.NewContext(r)

	datasetId := r.Get("dataset_id").String()
	if datasetId == "" {
		gplus.ResError(r, errors.New400Response("dataset_id 不能为空"))
		return
	}

	uploads := r.GetUploadFiles("file")
	if len(uploads) == 0 {
		gplus.ResError(r, errors.New400Response("请选择要上传的文件"))
		return
	}

	creatorId := gplus.GetUserId(r)
	params := make([]schema.UpdateFileParam, 0, len(uploads))
	for _, uf := range uploads {
		f, err := uf.Open()
		if err != nil {
			gplus.ResError(r, errors.New400Response(fmt.Sprintf("打开文件【%s】失败", uf.Filename)))
			return
		}
		data, err := io.ReadAll(f)
		_ = f.Close()
		if err != nil {
			gplus.ResError(r, errors.New400Response(fmt.Sprintf("读取文件【%s】失败", uf.Filename)))
			return
		}
		params = append(params, schema.UpdateFileParam{
			FileName:  uf.Filename,
			FileData:  data,
			FileSize:  uf.Size,
			DatasetId: datasetId,
			CreatorId: creatorId,
		})
	}

	if err := a.DatasetFileBll.BatchCreateV2(ctx, datasetId, params); err != nil {
		gplus.ResError(r, err)
		return
	}
	ResSuccess(r, nil)
}
