package controller

import (
	"net"
	"net/http"
	"pastebin_backend/app/response"
	//"pastebin_backend/model"

	//"error"
	"github.com/labstack/echo/v4"
	//"time"
	//"encoding/json"
	"fmt"
	"io"
	"os"
	//"github.com/google/uuid"
	//"github.com/go-playground/validator"
	//"github.com/sirupsen/logrus"
)

type File struct {
	FileName   string `json:"fileName"`
	FileType   string `json:"fileType"`
	Expiration int    `json:"expiration"`
	User       string `json:"user"`
	Passwd     string `json:"passwd"`
	//Expiry     time.Time `json:"expiry"` // 有效期
	//Content string `json:"content"`
}

type FileRe struct {
	FileName string `json:"fileName"`
	FileType string `json:"fileType"`
}

type pass struct {
	User   string `json:"user"`
	Passwd string `json:"passwd"`
}

type Text struct {
	text string `json:"text"`
}

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

// 通过用户名密码来设置cookie
func AskPasswd(c echo.Context) error {
	//
	info := new(pass)
	if err := c.Bind(info); err != nil {
		return err
	}
	if info.Passwd == "" || info.User == "" {
		//return c.String(http.StatusBadRequest, "请输入用户名和密码")
		c.String(http.StatusBadRequest, "请输入用户名和密码")
		return echo.ErrBadRequest
	}

	// 在数据库中查找，若user存在且密码一样，重置cookie有效期
	// user存在但密码不一样，密码错误或用户名已存在
	// user不存在，数据库中加记录并生成一个新的cookie

	SetCookie(c, info)
	return c.String(http.StatusOK, "cookie设置") //
	//return nil
}

// 设置cookie名为user，根据数据库分配uuid
func SetCookie(c echo.Context, info *pass) error {
	/*uuid, err := uuid.NewUUID()
	if err != nil {
		logrus.Fatal(err)
	}

	cookie := new(http.Cookie)
	cookie.Name = "user" // 标识为user
	//cookie.Value = string(uuid)  // 通过uuid和数据库，确定user是谁
	cookie.Value = "tmp"
	cookie.Path = "/"
	// cookie有效期为3600秒
	cookie.MaxAge = 3600

	// 在数据库中加入 cookie记录

	// 设置cookie
	c.SetCookie(cookie)*/
	return c.String(http.StatusOK, "cookie设置")
}

// 接收浏览器发来的文件，把文件储存在.\files\目录下
// 成功则返回上传成功，否则报错
func RecvFile(c echo.Context) error {
	file, err := c.FormFile("file")
	if err != nil {
		return err
	}

	// 打开用户上传的文件
	src, err := file.Open()
	if err != nil {
		return err
	}
	defer src.Close()

	info := new(File)
	if err = c.Bind(info); err != nil {
		return err
	}
	// 创建目标文件，就是我们打算把用户上传的文件保存到什么地方
	// file.Filename 参数指的是我们以用户上传的文件名，作为目标文件名，也就是服务端保存的文件名跟用户上传的文件名一样
	if info.FileType == "" {
		info.FileType = "txt"
	}
	filePath := "./files/" + info.FileType + "/" + file.Filename
	dst, err := os.Create(filePath)
	// 获取文件大小
	fi,_:=dst.Stat()
    if fi.Size()>8*1024*10224{
		c.HTML(http.StatusOK, fmt.Sprintf("<p>文件上传失败: 文件大小超过8MB</p>"))
	}

	if err != nil {
		fmt.Println(err)
		return err
	}
	defer dst.Close()

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

    // 更新数据库
	/*
	dinfo:=model.Users{
		Username: info.User,
		Passwd: info.Passwd,
		Name:info.FileName,// 无后缀
		Size: uint(fi.Size()),
		Route:filePath,
		//Time1: info.Expiry,
	}*/


	return c.HTML(http.StatusOK, fmt.Sprintf("<p>文件上传成功: %s</p>", file.Filename))
}

// 根据用户请求的文件名（不带后缀）和文件类型，返回对应文件的链接
func SendFile(c echo.Context) error {
	info := new(FileRe)
	if err := c.Bind(info); err != nil {
		return err
	}
	if info.FileType == "" {
		info.FileType = "txt"
	}
	filePath := "./files/" + info.FileType + "/" + info.FileName + "." + info.FileType
	src, err := os.Open(filePath)
	if err != nil {
		fmt.Println(err)
		return err
	}
	fi,err:=src.Stat()
	if err != nil{
		return err
	}
	
	defer func() {
		src.Close()
	}()
	
	data := make([]byte, fi.Size())
	count, err := src.Read(data)
	//return response.SendResponse(c, http.StatusOK, "", "pong!")
	count = count
	// 信息隐去
	c.JSON(http.StatusOK, info)
	return response.SendResponse(c, http.StatusOK, "msg", string(data))
	//return c.HTML(http.StatusOK, fmt.Sprintf("<p>文件上传成功: %s</p>", file.Filename))w
	//return nil
}

func RecvText(c echo.Context) error {
	text := new(Text)
	if err := c.Bind(text); err != nil {
		fmt.Println(err)
		return err
	}
	//return text.text
	return nil
}

func SendText(conn net.Conn, text Text) error {
	buf := []byte(text.text)
	_, err := conn.Write(buf[:])
	if err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}

// 如果没有对应文件夹就建立
func fileTypeJudge(fileType string) error {
	return nil
}
