package main

import (
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"net/http"
	"path/filepath"
	"regexp"
	"strconv"

	"redisdog/model"
)

type SyscfgAccountListRet struct {
	Errno int                  `json:"errno"`
	Error string               `json:"error"`
	Data  []*model.AccountsRow `json:"data"`
}

type SyscfgAccountGetRet struct {
	Errno int                `json:"errno"`
	Error string             `json:"error"`
	Data  *model.AccountsRow `json:"data"`
}

func syscfg_account(resp http.ResponseWriter, req *http.Request) {
	sess, ok := checkLogin(resp, req)
	if !ok {
		return
	}
	if !sess.Account.IsSuper {
		resp.Header().Set("Location", "/index/forbidden")
		resp.WriteHeader(302)
		return
	}
	//视图输出
	files := []string{
		filepath.Join(Cfg.TmplDir, "syscfg", "account.tmpl"),
		filepath.Join(Cfg.TmplDir, "header.tmpl"),
		filepath.Join(Cfg.TmplDir, "navbar.tmpl"),
	}
	tmpl, err := template.New("account.tmpl").Funcs(TmplFuncMap).ParseFiles(files...)
	if err != nil {
		io.WriteString(resp, fmt.Sprintf("Error: %s\n", err.Error()))
	} else {
		tmpl.Execute(resp, struct {
			Sess  *Session
			Req   *http.Request
			Title string
		}{
			sess,
			req,
			"账号管理",
		})
	}
}

func syscfg_account_list(resp http.ResponseWriter, req *http.Request) {
	sess, ok := checkLogin(resp, req)
	if !ok {
		return
	}
	if !sess.Account.IsSuper {
		ret, _ := json.Marshal(ErrorRet{Errno: 404, Error: "Forbidden"})
		resp.Write(ret)
		return
	}
	req.ParseForm()
	mdlAccounts := model.NewAccounts(Db)
	list, err := mdlAccounts.GetAll()
	if err != nil {
		resp.Write(ERROR_RET(1, err.Error()))
	} else {
		ret, _ := json.Marshal(SyscfgAccountListRet{Errno: 0, Error: "", Data: list})
		resp.Write(ret)
	}
}

func syscfg_account_get(resp http.ResponseWriter, req *http.Request) {
	sess, ok := checkLogin(resp, req)
	if !ok {
		return
	}
	if !sess.Account.IsSuper {
		ret, _ := json.Marshal(ErrorRet{Errno: 404, Error: "Forbidden"})
		resp.Write(ret)
		return
	}
	req.ParseForm()
	idStr := req.Form.Get("id")
	if idStr == "" {
		resp.Write(ERROR_RET(1, "ID不能为空！"))
		return
	}
	id, err := strconv.Atoi(idStr)
	if err != nil {
		resp.Write(ERROR_RET(2, err.Error()))
		return
	}
	mdlAccounts := model.NewAccounts(Db)
	item, err := mdlAccounts.Get(int64(id))
	if err != nil {
		resp.Write(ERROR_RET(3, err.Error()))
	} else {
		ret, _ := json.Marshal(SyscfgAccountGetRet{Errno: 0, Error: "", Data: item})
		resp.Write(ret)
	}
}

func syscfg_account_set(resp http.ResponseWriter, req *http.Request) {
	sess, ok := checkLogin(resp, req)
	if !ok {
		return
	}
	if !sess.Account.IsSuper {
		ret, _ := json.Marshal(ErrorRet{Errno: 404, Error: "Forbidden"})
		resp.Write(ret)
		return
	}
	req.ParseForm()
	Id := req.PostForm.Get("Id")
	Account := req.PostForm.Get("Account")
	Name := req.PostForm.Get("Name")
	Password := req.PostForm.Get("Password")
	IsSuper := req.PostForm.Get("IsSuper")
	Disabled := req.PostForm.Get("Disabled")
	IdInt, err := strconv.Atoi(Id)
	if err != nil {
		IdInt = 0
	}
	if Account == "" {
		resp.Write(ERROR_RET(1, "账号不能为空！"))
		return
	}
	reg := regexp.MustCompile(`^[A-Za-z]\w{1,19}$`)
	if !reg.MatchString(Account) {
		resp.Write(ERROR_RET(2, "账号格式不正确！"))
		return
	}
	if Name == "" {
		resp.Write(ERROR_RET(3, "姓名不能为空！"))
		return
	}
	if IdInt == 0 {
		if Password == "" {
			resp.Write(ERROR_RET(4, "密码不能为空！"))
			return
		}
		if len(Password) < 6 {
			resp.Write(ERROR_RET(5, "密码长度不能小于6！"))
			return
		}
	}
	if IsSuper == "" {
		resp.Write(ERROR_RET(6, "请选择是否管理员！"))
		return
	}
	if Disabled == "" {
		resp.Write(ERROR_RET(7, "状态不能为空！"))
		return
	}
	IsSuperInt, err := strconv.Atoi(IsSuper)
	if err != nil {
		resp.Write(ERROR_RET(8, err.Error()))
		return
	}
	DisabledInt, err := strconv.Atoi(Disabled)
	if err != nil {
		resp.Write(ERROR_RET(9, err.Error()))
		return
	}
	newRow := model.AccountsRow{
		Id:       int64(IdInt),
		Account:  Account,
		Name:     Name,
		Password: Password,
		IsSuper:  IsSuperInt != 0,
		Disabled: DisabledInt != 0,
	}
	mdlAccounts := model.NewAccounts(Db)
	if IdInt > 0 {
		affected, err := mdlAccounts.Update(&newRow)
		if err != nil {
			resp.Write(ERROR_RET(10, err.Error()))
		} else if affected > 0 {
			resp.Write(ERROR_RET(0, ""))
		} else {
			resp.Write(ERROR_RET(11, "更新失败！"))
		}
	} else {
		newRowId, err := mdlAccounts.Insert(&newRow)
		if err != nil {
			resp.Write(ERROR_RET(22, err.Error()))
		} else if newRowId > 0 {
			ret, _ := json.Marshal(SyscfgRedisAddRet{Errno: 0, Error: "", Data: newRowId})
			resp.Write(ret)
		} else {
			resp.Write(ERROR_RET(23, "新增失败！"))
		}
	}
}

func syscfg_account_del(resp http.ResponseWriter, req *http.Request) {
	sess, ok := checkLogin(resp, req)
	if !ok {
		return
	}
	if !sess.Account.IsSuper {
		ret, _ := json.Marshal(ErrorRet{Errno: 404, Error: "Forbidden"})
		resp.Write(ret)
		return
	}
	req.ParseForm()
	idStr := req.Form.Get("id")
	if idStr == "" {
		resp.Write(ERROR_RET(1, "ID不能为空！"))
		return
	}
	id, err := strconv.Atoi(idStr)
	if err != nil {
		resp.Write(ERROR_RET(2, err.Error()))
		return
	}
	mdlAccounts := model.NewAccounts(Db)
	affected, err := mdlAccounts.Delete(int64(id))
	if err != nil {
		resp.Write(ERROR_RET(3, err.Error()))
	} else if affected > 0 {
		resp.Write(ERROR_RET(0, ""))
		SYSLOG("WARN", fmt.Sprintf("管理员#%d %s %s删除了账号 #%d", sess.Account.Id, sess.Account.Name, sess.Account.Account, id))
	} else {
		resp.Write(ERROR_RET(4, "操作失败！"))
	}
}

func syscfg_account_reset_pwd(resp http.ResponseWriter, req *http.Request) {
	sess, ok := checkLogin(resp, req)
	if !ok {
		return
	}
	if !sess.Account.IsSuper {
		ret, _ := json.Marshal(ErrorRet{Errno: 404, Error: "Forbidden"})
		resp.Write(ret)
		return
	}
	req.ParseForm()
	idStr := req.PostForm.Get("id")
	if idStr == "" {
		resp.Write(ERROR_RET(1, "ID不能为空！"))
		return
	}
	id, err := strconv.Atoi(idStr)
	if err != nil {
		resp.Write(ERROR_RET(2, err.Error()))
		return
	}
	password := req.PostForm.Get("password")
	if len(password) < 6 {
		resp.Write(ERROR_RET(3, "密码长度不能小于6位！"))
		return
	}
	mdlAccounts := model.NewAccounts(Db)
	affected, err := mdlAccounts.UpdatePassword(int64(id), password)
	if err != nil {
		resp.Write(ERROR_RET(4, err.Error()))
	} else if affected > 0 {
		resp.Write(ERROR_RET(0, ""))
		SYSLOG("WARN", fmt.Sprintf("管理员#%d %s %s修改了账号 #%d的密码", sess.Account.Id, sess.Account.Name, sess.Account.Account, id))
	} else {
		resp.Write(ERROR_RET(5, "操作失败！"))
	}
}
