package controller

import (
	"backend/app/response"
	"backend/model"
	"fmt"
	"io"
	"net/http"
	"time"

	"github.com/labstack/echo/v4"
	"github.com/sirupsen/logrus"
)

type File struct {
	FileName   string    `json:"fileName" form:"fileName" query:"fileName"`
	FileType   string    `json:"fileType" form:"fileType" query:"fileName"`
	Expiration int       `json:"expiration" form:"expiration" query:"expiration"`
	User       string    `json:"user" form:"user" query:"user"`
	Passwd     string    `json:"passwd" form:"passwd" query:"passwd"`
	Url        string    `json:"url" form:"url" query:"url"`
	Time       time.Time `json:"time" form:"time" query:"time"`               // 用户指定的时间期限
	MaxAccess  uint      `json:"maxaccess form:"maxaccess" query:"maxaccess"` // 文件最大可访问次数
	//Expiry     time.Time `json:"expiry"` // 有效期
	//Content string `json:"content"`
}

func Ping(c echo.Context) error {
	// just test
	return response.SendResponse(c, http.StatusOK, "", "pong!")
}

// 接收浏览器发来的文件，把文件储存在.\files\目录下
// 成功则返回上传成功，否则报错
// sessionId不直接绑定，通过cookie传
func RecvFile(c echo.Context) error {
	info := new(File)
	src, err := srcRead(c, info)
	if err != nil {
		return response.SendResponse4(c, err) // log在srcRead里进行
	}
	info.Time = timeAssign(info.Time) // 默认时间
	// 创建目标文件，就是我们打算把用户上传的文件保存到什么地方
	// info.Filename 参数指的是我们以用户上传的文件名，作为目标文件名，也就是服务端保存的文件名跟用户上传的文件名一样
	dst, filePath := dstCreate(info)
	//dst, _ := dstCreate(info)
	defer dst.Close()

	if !overflow(dst, 8*1024*1024) {
		return c.HTML(http.StatusOK, "<p>error:文件上传失败: 文件大小超过8MB</p>")
	}

	// 这里将用户上传的文件复制到服务端的目标文件
	if _, err = io.Copy(dst, src); err != nil {
		logrus.Println(err)
		return err
	}

	// api 分配

	// 更新数据库
	_, url := DBupdate(c, filePath, info) // 不分配uid
	//sid := "fakesid" //
	//url := "fakeurl" //
	//cookie := new(http.Cookie)
	return response.SendResponse2(c, http.StatusOK, GetFileContentType(info.FileType), fmt.Sprintf("文件上传成功： %s", info.FileName), url)
}

/*
 * 输入：前端提供的文件链接，
 * 返回：一个可供URL访问的链接（string）
 * cookie.Value 传sessionId
 */
func SendFile(c echo.Context) error {
	info := new(File)
	if err := c.Bind(info); err != nil {
		logrus.Println(err)
		return err
	}
	info.Time = timeAssign(info.Time) // 默认时间为当前半小时后

	cookie, _ := c.Cookie("User")
	if cookie == nil {
		c.HTML(http.StatusBadRequest, "没有cookie,已分配.\n")
		cookie = new(http.Cookie)
		SetCookie(c, cookie, IdGen(8), 1800, time.Time{})
	}

	// 鉴权
	stat := Autheticate(cookie, info.Url, info.Passwd, info.Time) // 包含创建链接Createlink
	switch stat {
	case 0:
		return c.HTML(http.StatusForbidden, "error:密码错误") // 403
	case 1: // 鉴权通过
		info.FileType = TypeComplement(info.FileType) // 格式化后缀，仿止出错
		//stat:=model.Createlink(cookie.Value,info.Passwd,info.Url,info.Time)
		filePath := model.Findlink(info.Url)
		data := readFile(filePath)
		c.JSON(http.StatusOK, info)
		return response.SendResponse3(c, http.StatusOK, GetFileContentType(info.FileType), data) // 返回数据
	case 2:
		return c.HTML(http.StatusGone, "error:内容过期")
	case 3:
		return c.HTML(http.StatusUnauthorized, "请进行身份验证")

	}
	return nil
}

// 申请一个包含uid的cookie
func AskUid(c echo.Context) error {
	nsid := IdGen(8)
	info := new(File)
	cookie := new(http.Cookie)
	err := SetCookie(c, cookie, nsid, info.Expiration, info.Time)
	if err != nil {
		return err
	} else {
		return c.HTML(http.StatusOK, "success")
	}

}
