/*
 * @description:工程项目数据库操作
 * @Author: CP
 * @Date: 2020-09-03 14:40:06
 * @FilePath: \construction_management\dao\project_dao.go
 */
package dao

import (
	"errors"
	"log"
	"strings"

	"github.com/go-xorm/xorm"
	"go.mod/models"
	"go.mod/web/viewmodels"
)

// 数据库操作引擎
type ProjectDao struct {
	engine *xorm.Engine
}

// 获得一个DAO对象
func NewProjectDao(engine *xorm.Engine) *ProjectDao {
	return &ProjectDao{
		engine: engine,
	}
}

// CmProjectAccount 设置的值获得数据
func (d *ProjectDao) Get(id int) *models.CmProject {
	data := &models.CmProject{}
	_, err := d.engine.
		Where("id=? ", id).
		Get(data)
	if err != nil {
		data.Id = 0
		return data
	}
	return data
}

func (d *ProjectDao) GetPage(page int, size int) []models.CmProject {
	datalist := make([]models.CmProject, 0)
	if page == 1 {
		page = 0
	} else {
		page--
		page = page * size
	}
	// Where("project_id = ? and bidsection_id =? and contracts_id=?", projectId, bidsectionId, contractsId).
	_ = d.engine.
		Limit(size, page).
		Find(&datalist)
	return datalist
}

func (d *ProjectDao) GetPageBsByCategory(pageData viewmodels.ProjectPage, category string) (data []models.CmProject, total int64) {
	datalist := make([]models.CmProject, 0)
	page := pageData.Page
	size := pageData.Size
	if page == 1 {
		page = 0
	} else {
		page--
		page = page * size
	}

	Project := &models.CmProject{}

	sql := ""
	var args = make([]interface{}, 0)

	// if len(pageData.InsideCategoryId) > 0 {
	if category != "" {
		sql += "inside_categoryId = ?"
		args = append(args, category)
	}

	// if category != "" {
	// 	sql += "inside_category = ?"

	// }

	if pageData.Search != "" {
		args = append(args, "%"+pageData.Search+"%")
		args = append(args, "%"+pageData.Search+"%")
		search := "(code like ? or  name like ?)"
		if sql != "" {
			sql = strings.Join([]string{sql, search}, " and ")
		} else {
			sql = search
		}
	}

	count, _ := d.engine.
		Where(sql, args...).
		Count(Project)
	_ = d.engine.
		Where(sql, args...).
		Limit(size, page).
		Find(&datalist)
	return datalist, count
}

func (d *ProjectDao) GetPageBsByStaffName(pageData viewmodels.ProjectPage, staffName string) (data []models.CmProject, total int64) {
	datalist := make([]models.CmProject, 0)
	page := pageData.Page
	size := pageData.Size
	if page == 1 {
		page = 0
	} else {
		page--
		page = page * size
	}

	Project := &models.CmProject{}

	sql := ""
	var args = make([]interface{}, 0)

	if staffName != "" {
		sql += "staff_name = ?"
		args = append(args, staffName)
	}

	if pageData.Search != "" {
		args = append(args, pageData.Search)
		args = append(args, pageData.Search)
		search := "(code like ? or  name like ?)"
		sql = strings.Join([]string{sql, search}, " and ")
	}

	count, _ := d.engine.
		Where(sql, args...).
		Count(Project)
	_ = d.engine.
		Where(sql, args...).
		Limit(size, page).
		Find(&datalist)
	return datalist, count

	// if pageData.Search != "" {
	// 	count, _ := d.engine.
	// 		Where(" (code like ? or  name like ?) and staff_name = ? ", arr...).
	// 		Count(Project)
	// 	_ = d.engine.
	// 		Where(" (code like ? or  name like ?)  and staff_name = ? ", pageData.Search, pageData.Search).
	// 		Limit(size, page).
	// 		Find(&datalist)
	// 	return datalist, count
	// }

	// // Where("project_id = ? and bidsection_id =? and contracts_id=?", projectId, bidsectionId, contractsId).
	// count, _ := d.engine.Count(Project)
	// _ = d.engine.
	// 	Limit(size, page).
	// 	Find(&datalist)
	// return datalist, count
}

func (d *ProjectDao) GetPageBs(pageData viewmodels.ProjectPage) (data []models.CmProject, total int64) {
	datalist := make([]models.CmProject, 0)
	page := pageData.Page
	size := pageData.Size
	if page == 1 {
		page = 0
	} else {
		page--
		page = page * size
	}

	Project := &models.CmProject{}

	// 多余判断
	InsideCategoryId := ""

	if len(pageData.InsideCategoryId) > 0 {
		InsideCategoryId = pageData.InsideCategoryId[0]
	}

	if InsideCategoryId != "" && pageData.Search != "" {
		count, _ := d.engine.
			Where("insideCategoryId= ? and (code like ? or  name like ?) ", InsideCategoryId, pageData.Search, pageData.Search).
			Count(Project)
		_ = d.engine.
			Where("insideCategoryId= ? and (code like ? or  name like ?) ", InsideCategoryId, pageData.Search, pageData.Search).
			Limit(size, page).
			Find(&datalist)
		return datalist, count
	}

	if InsideCategoryId != "" {
		count, _ := d.engine.
			Where("insideCategoryId= ?", InsideCategoryId).
			Count(Project)
		_ = d.engine.
			Where("insideCategoryId= ?", InsideCategoryId).
			Limit(size, page).
			Find(&datalist)
		return datalist, count
	}

	if pageData.Search != "" {
		count, _ := d.engine.
			Where(" code like ? or  name like ? ", pageData.Search, pageData.Search).
			Count(Project)
		_ = d.engine.
			Where(" code like ? or  name like ? ", pageData.Search, pageData.Search).
			Limit(size, page).
			Find(&datalist)
		return datalist, count
	}

	// Where("project_id = ? and bidsection_id =? and contracts_id=?", projectId, bidsectionId, contractsId).
	count, _ := d.engine.Count(Project)
	_ = d.engine.
		Limit(size, page).
		Find(&datalist)
	return datalist, count
}

// 设置的值获得数据
func (d *ProjectDao) GetCode(code string) *models.CmProject {
	data := &models.CmProject{}

	ok, err := d.engine.
		Where("code = ?", code).
		Get(data)
	if ok && err == nil {
		return data
	} else {
		data.Id = 0
		return data
	}
}

// 获得一组项目数据
func (d *ProjectDao) GetListByCode(code string) []models.CmProject {
	datalist := make([]models.CmProject, 0)

	err := d.engine.
		Where("code = ?", code).
		Desc("id").
		Find(&datalist)
	if err != nil {
		return datalist
	} else {
		return datalist
	}
}

// 新增
func (d *ProjectDao) Add(data *models.CmProject) error {
	_, err := d.engine.Insert(data)
	return err
}

// 创建项目和管理员账号
func (d *ProjectDao) AddProjectAndAccount(projectData *models.CmProject, accountData *models.CmProjectAccount) error {
	session := d.engine.NewSession()
	defer session.Close()
	err := session.Begin()
	if err != nil {
		return errors.New("新增项目出错-db")
	}

	// 1.写入项目表
	if _, err = session.Insert(projectData); err != nil {
		log.Println(err)
		session.Rollback()
		return errors.New("新增项目出错")
	}

	// 2.写入账号表
	accountData.ProjectId = projectData.Id
	_, err = session.Insert(accountData)
	if err != nil {
		log.Println(err)
		session.Rollback()
		return errors.New("新增账号出错")
	}

	// 更新项目表里的管理员信息
	updateData := &models.CmProject{}
	updateData.Id = projectData.Id
	updateData.UserId = accountData.Id
	updateData.UserAccount = accountData.Name
	if _, err = session.Where("id = ? ", projectData.Id).Update(updateData); err != nil {
		log.Println(err)
		session.Rollback()
		return errors.New("更新管理员信息出错")
	}

	// 3. 提交事务
	err = session.Commit()
	if err != nil {
		session.Rollback()
		return errors.New("新增项目出错-db")
	}
	return nil
}

// 更新
func (d *ProjectDao) Update(data *models.CmProject, columns []string) error {
	//_, err := d.engine.Id(data.Id).MustCols(columns...).Update(data)
	_, err := d.engine.Where("id = ?  ", data.Id).MustCols(columns...).Update(data)
	return err
}

func (d *ProjectDao) FindById(id int) (*models.CmProject, error) {
	data := &models.CmProject{}
	_, err := d.engine.Where("id=?", id).Get(data)
	return data, err
}
