package dao

import (
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
	"server/global"
)

type Project struct {
	global.GVA_MODEL
	Code                 string                `json:"code" form:"code" gorm:"comment:项目编号"`
	Name                 string                `json:"name" form:"name" gorm:"comment:项目名称"`
	Address              string                `json:"address" form:"address" gorm:"comment:项目地址"`
	FirstPrincipal       string                `json:"firstPrincipal" form:"firstPrincipal" gorm:"comment:甲方负责人"`
	FirstPhone           string                `json:"firstPhone" form:"firstPhone" gorm:"comment:甲方电话"`
	ProjectPrice         float64               `json:"projectPrice" form:"projectPrice" gorm:"type:decimal(10,2);comment:合同金额"`
	SecondPrincipal      int                   `json:"secondPrincipal" form:"secondPrincipal" gorm:"comment:乙方负责人"`
	Principal            SysUser               `json:"principal" form:"principal" gorm:"foreignKey:SecondPrincipal;references:id;"`
	SecondPrincipalName  string                `json:"secondPrincipalName" form:"secondPrincipalName" gorm:"comment:乙方姓名"`
	SignTime             string                `json:"signTime" form:"signTime" gorm:"comment:合同签订日期"`
	IntoConstructionTime string                `json:"intoConstructionTime" form:"intoConstructionTime" gorm:"comment:进场施工时间"`
	CompletedTime        string                `json:"completedTime" form:"completedTime" gorm:"comment:竣工时间"`
	SupervisorUint       string                `json:"supervisorUint" form:"supervisorUint" gorm:"comment:监理单位"`
	SupervisorName       string                `json:"supervisorName" form:"supervisorName" gorm:"comment:监理姓名"`
	SupervisorPhone      string                `json:"supervisorPhone" form:"supervisorPhone" gorm:"comment:监理电话"`
	Illustrate           string                `json:"illustrate" form:"illustrate" gorm:"comment:说明;type:varchar(200)"`
	State                int                   `json:"state" form:"state" gorm:"comment:状态"`
	ProjectState         ProjectState          `json:"projectState" form:"projectState" gorm:"foreignKey:State;references:id;"`
	CollectionTime       string                `json:"collectionTime" form:"collectionTime" gorm:"comment:收款时间"`
	EndTime              string                `json:"endTime" form:"endTime" gorm:"comment:结束时间"`
	Files                []ProjectFile         `json:"files" form:"files" gorm:"-"`
	WorkingHours         []ProjectWorkingHours `json:"workingHours" form:"workingHours" gorm:"-"`
	WorkingHoursTotal    int64                 `json:"workingHoursTotal" form:"workingHoursTotal" gorm:"-"`
	Collection           []Collection          `json:"collection" form:"collection" gorm:"-"`
	CollectionTotal      int64                 `json:"collectionTotal" form:"collectionTotal" gorm:"-"`
	Reimbursement        []Reimbursement       `json:"reimbursement" form:"reimbursement" gorm:"-"`
	ReimbursementTotal   int64                 `json:"reimbursementTotal" form:"reimbursementTotal" gorm:"-"`
	ProjectFee           []ProjectFee          `json:"projectFee" form:"project" gorm:"-"`
	ProjectFeeTotal      int64                 `json:"projectFeeTotal" form:"projectFeeTotal" gorm:"-"`
}

func (Project) TableName() string {
	return "project"
}

// TODO:项目查询

// QueryProjectList 查询项目列表
func QueryProjectList(limit, offset, state int, name, time string) (project []Project, total int64, err error) {
	// 创建db
	db := global.GVA_DB.Model(&Project{})
	// 如果有条件搜索 下方会自动创建搜索语句
	if state != 0 {
		db = db.Where("state = ?", state)
	}
	if name != "" {
		db = db.Where("name LIKE ?", "%"+name+"%")
	}
	if time != "" {
		db = db.Where("DATE_FORMAT(created_at, '%Y-%m') = ?", time)
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Order("id desc").Limit(limit).Offset(offset).Preload("Principal").Preload("ProjectState").Find(&project).Error

	for i, p := range project {
		project[i].SecondPrincipalName = p.Principal.NickName
	}

	return project, total, err
}

// QueryProjectByCode 查询单个项目  按编号
func QueryProjectByCode(code string) (project Project, err error) {
	err = global.GVA_DB.Model(&Project{}).Where("code = ?", code).Preload("Principal").Preload("ProjectState").First(&project).Error
	project.SecondPrincipalName = project.Principal.NickName
	return
}

// QueryAllProject 查询所以项目
func QueryAllProject() (projects []Project, err error) {
	err = global.GVA_DB.Model(&Project{}).Find(&projects).Error
	return projects, err
}

// TODO:项目新增

// CreateProject 新增项目
func (p Project) CreateProject() error {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		txErr := tx.Model(&Project{}).Create(&p).Error
		if txErr != nil {
			return txErr
		}

		for _, file := range p.Files {
			var isFile ProjectFile
			tx.Model(&ProjectFile{}).Where("project_code = ? AND name = ? AND genre = ?", file.ProjectCode, file.Name, file.Genre).First(&isFile)
			if isFile.ID != 0 {
				txErr := tx.Model(&ProjectFile{}).Where("id = ?", isFile.ID).Updates(&file).Error
				if txErr != nil {
					return txErr
				}
			} else {
				txErr := tx.Model(&ProjectFile{}).Create(&file).Error
				if txErr != nil {
					return txErr
				}
			}
		}
		return txErr
	})
}

type ProjectSum struct {
	TotalProjectAmount    float64
	TotalCollectionAmount float64
	Receivables           float64
}

// QueryProjectSum 查询项目总
func QueryProjectSum(code string) (projectSum ProjectSum, err error) {
	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		projectDB := tx.Model(&Project{}).Select("SUM(project_price) AS total_project_amount")
		collectionDB := tx.Model(&Collection{}).Select("SUM(collection_price) AS total_collection_amount")
		if code != "" {
			projectDB = projectDB.Where("code =?", code)
			collectionDB = collectionDB.Where("project_code =?", code)
		}

		txErr := projectDB.First(&projectSum).Error
		if txErr != nil {
			return txErr
		}
		txErr = collectionDB.First(&projectSum).Error
		if txErr != nil {
			return txErr
		}
		return txErr
	})
	// 使用decimal 防止精度不准
	exponent := decimal.NewFromFloatWithExponent(projectSum.TotalProjectAmount-projectSum.TotalCollectionAmount, -2)
	projectSum.Receivables = exponent.InexactFloat64()
	return
}

// TODO:项目修改

// UpdateProject 修改项目
func (p Project) UpdateProject() error {
	return global.GVA_DB.Model(&p).Where("id = ?", p.ID).Updates(p).Error
}

// TODO:项目删除

// DeleteProject 删除项目
func DeleteProject(code string) error {
	return global.GVA_DB.Unscoped().Where("code = ?", code).Delete(&Project{}).Error
}
