package services

import (
	"errors"
	"fmt"
	"gin-vue-admin/common"
	"gin-vue-admin/models"
	"gin-vue-admin/repository"
	"gin-vue-admin/utils"
	"strings"
)

// GetExpendCode 获取支出单号
func GetExpendCode(phone string) (interface{}, error) {

	// 1. 查询当前手机号是否有默认医院
	chainCode, employeeLocalID, err := repository.QueryChainCodeAndLocalIDByPhone(phone)
	if err != nil {
		return nil, err
	}

	if chainCode == "" {
		return nil, errors.New("请设置默认医院")
	}

	// 2. 拿到db
	safeMap := common.NewSafeMap()
	db, err := safeMap.GetOrStore(chainCode)
	if err != nil {
		return nil, err
	}

	hospitalID, err := repository.GetHospitalID(db, employeeLocalID)
	if err != nil {
		return nil, err
	}

	code, err := repository.GetCodeByTable(db, hospitalID, common.OutChargeTable, common.OutChargeTag)
	if err != nil {
		return nil, err
	}

	m := map[string]string{
		"order_number": code,
	}

	return m, nil
}

// QueryExpends 查询支出管理列表
func QueryExpends(phone, month string, page, pageSize int64) (interface{}, error) {

	// 1. 查询当前手机号是否有默认医院
	chainCode, _, err := repository.QueryChainCodeAndLocalIDByPhone(phone)
	if err != nil {
		return nil, err
	}

	if chainCode == "" {
		return nil, errors.New("请设置默认医院")
	}

	// 2. 拿到db
	safeMap := common.NewSafeMap()
	db, err := safeMap.GetOrStore(chainCode)
	if err != nil {
		return nil, err
	}

	total, err := repository.QueryExpendCount(db, month)
	if err != nil {
		return nil, err
	}

	pageSize, page, pageData := utils.GetPageData(page, pageSize, total)

	response, err := repository.QueryExpends(db, month, page, pageSize)
	if err != nil {
		return nil, err
	}

	sumMoney, err := repository.QueryExpendsSumMoney(db, month)
	if err != nil {
		return nil, err
	}

	pageData.Data = response

	var r models.Response

	r.PageData = pageData
	r.SumMoney = sumMoney

	return r, nil
}

func QueryExpendDetail(phone string, id int64) (interface{}, error) {

	// 1. 查询当前手机号是否有默认医院
	chainCode, _, err := repository.QueryChainCodeAndLocalIDByPhone(phone)
	if err != nil {
		return nil, err
	}

	if chainCode == "" {
		return nil, errors.New("请设置默认医院")
	}

	// 2. 拿到db
	safeMap := common.NewSafeMap()
	db, err := safeMap.GetOrStore(chainCode)
	if err != nil {
		return nil, err
	}

	row := db.QueryRow(`select _code, _usage,convert(money/1000,decimal(11,3)) as money, 
	happentime, operate_employee_id, operate_employee_name, discription, type, device_type, 
	convert(deprerate/1000,decimal(11,3)) deprerate, depreyear, starttime, endtime, createtime 
	from c_outcharge where id=? limit 1`, id)

	model := &models.ExpendInfo{ID: id}
	err = row.Scan(&model.OrderCode, &model.Usage, &model.Money, &model.HappenTime,
		&model.OperateID, &model.OperateName, &model.Description, &model.ExpendType,
		&model.DeviceType, &model.DepreRate, &model.DepreYear, &model.AmortizeStartTime,
		&model.AmortizeEndTime, &model.EventTime)
	if err != nil {
		return nil, err
	}

	payrows, err := db.Query("select id,paytype,convert(money/1000,decimal(11,3)) as money from c_outcharge_pay where delflag=0 and c_outcharge_id=?", id)
	if err != nil {
		return nil, err
	}
	for payrows.Next() {
		payModel := models.PayModel{}
		err = payrows.Scan(&payModel.ID, &payModel.Type, &payModel.Money)
		if err != nil {
			return nil, err
		}
		model.PayData = append(model.PayData, payModel)
	}

	return model, nil
}

func AddExpend(phone string, p *models.ExpendInfo) error {

	// 1. 查询当前手机号是否有默认医院
	chainCode, employeeLocalID, err := repository.QueryChainCodeAndLocalIDByPhone(phone)
	if err != nil {
		return err
	}

	if chainCode == "" {
		return errors.New("请设置默认医院")
	}

	// 2. 拿到db
	safeMap := common.NewSafeMap()
	db, err := safeMap.GetOrStore(chainCode)
	if err != nil {
		return err
	}

	hospitalID, err := repository.GetHospitalID(db, employeeLocalID)
	if err != nil {
		return err
	}

	tx, err := db.Begin()
	if err != nil {
		return err
	}

	result, err := tx.Exec("insert into c_outcharge(creater,sys_hospital_id,_code,_usage,money,happentime,operate_employee_id,operate_employee_name,discription,type,device_type,deprerate,depreyear,starttime,endtime) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
		employeeLocalID, hospitalID, p.OrderCode, p.Usage, p.Money*1000, p.HappenTime, p.OperateID, p.OperateName, p.Description, p.ExpendType, p.DeviceType, p.DepreRate*1000, p.DepreYear, p.AmortizeStartTime, p.AmortizeEndTime)
	if err != nil {
		tx.Rollback()
		return err
	}
	resultId, err := result.LastInsertId()
	if err != nil {
		tx.Rollback()
		return err
	}
	for _, value := range p.PayData {
		r, err := tx.Exec("insert into c_outcharge_pay(creater,sys_hospital_id,c_outcharge_id,paytype,money,eventtime) values(?,?,?,?,?,?)",
			employeeLocalID, hospitalID, resultId, value.Type, value.Money*1000, p.HappenTime)
		if err != nil {
			tx.Rollback()
			return err
		}
		payId, err := r.LastInsertId()
		if err != nil {
			tx.Rollback()
			return err
		}
		_, err = tx.Exec("insert into c_cashflow(creater,sys_hospital_id,bussiness_id,bussiness_type,pay_type,money,eventime) values(?,?,?,?,?,?,?)",
			employeeLocalID, hospitalID, payId, 8, value.Type, value.Money*(-1000), p.HappenTime)
		if err != nil {
			tx.Rollback()
			return err
		}
	}
	err = tx.Commit()
	if err != nil {
		tx.Rollback()
		return err
	}

	return nil
}

func UpdateExpend(phone string, p *models.ExpendInfo) error {

	// 1. 查询当前手机号是否有默认医院
	chainCode, employeeLocalID, err := repository.QueryChainCodeAndLocalIDByPhone(phone)
	if err != nil {
		return err
	}

	if chainCode == "" {
		return errors.New("请设置默认医院")
	}

	// 2. 拿到db
	safeMap := common.NewSafeMap()
	db, err := safeMap.GetOrStore(chainCode)
	if err != nil {
		return err
	}

	hospitalID, err := repository.GetHospitalID(db, employeeLocalID)
	if err != nil {
		return err
	}

	tx, err := db.Begin()
	if err != nil {
		return err
	}

	_, err = tx.Exec("update c_outcharge set updater=?,happentime=?,_usage=?,money=?,operate_employee_id=?,operate_employee_name=?,discription=?,type=?,device_type=?,deprerate=?,depreyear=?,starttime=?,endtime=? where id=?",
		employeeLocalID, p.HappenTime, p.Usage, p.Money*1000, p.OperateID, p.OperateName, p.Description, p.ExpendType, p.DeviceType, p.DepreRate, p.DepreYear, p.AmortizeStartTime, p.AmortizeEndTime, p.ID)
	if err != nil {
		tx.Rollback()
		return err
	}
	delids := ""
	for _, value := range p.PayData {
		if value.ID == 0 {
			result, err := tx.Exec("insert into c_outcharge_pay(creater,sys_hospital_id,c_outcharge_id,paytype,money,eventtime) values(?,?,?,?,?,?)",
				employeeLocalID, hospitalID, p.ID, value.Type, value.Money*1000, p.HappenTime)
			if err != nil {
				tx.Rollback()
				return err
			}
			value.ID, err = result.LastInsertId()
			if err != nil {
				tx.Rollback()
				return err
			}
			_, err = tx.Exec("insert into c_cashflow(creater,sys_hospital_id,bussiness_id,bussiness_type,pay_type,money,eventime) values(?,?,?,?,?,?,?)",
				employeeLocalID, hospitalID, value.ID, 8, value.Type, value.Money*(-1000), p.HappenTime)
			if err != nil {
				tx.Rollback()
				return err
			}
		} else {
			_, err = tx.Exec("update c_outcharge_pay set updater=?,money=?,eventtime=? where id=?",
				employeeLocalID, value.Money*1000, p.HappenTime, value.ID)
			if err != nil {
				tx.Rollback()
				return err
			}
			_, err = tx.Exec("update c_cashflow set updater=?,money=?,eventime=? where bussiness_id=? and bussiness_type=8", employeeLocalID, value.Money*(-1000), p.HappenTime, value.ID)
			if err != nil {
				tx.Rollback()
				return err
			}
		}
		delids = fmt.Sprintf("%s%d,", delids, value.ID)
	}
	delids = strings.TrimRight(delids, ",")
	_, err = tx.Exec("update c_outcharge_pay set updater=?,delflag=1 where c_outcharge_id=? and delflag=0 and id not in ("+delids+")", employeeLocalID, p.ID)
	if err != nil {
		tx.Rollback()
		return err
	}
	_, err = tx.Exec("update c_cashflow set updater=?,delflag=1 where delflag=0 and bussiness_type=8 and bussiness_id in (select id from c_outcharge_pay where c_outcharge_id=? and delflag=1) ", employeeLocalID, p.ID)
	if err != nil {
		tx.Rollback()
		return err
	}
	err = tx.Commit()
	if err != nil {
		tx.Rollback()
		return err
	}

	return nil
}

func DeleteExpend(phone string, expendID string) error {

	// 1. 查询当前手机号是否有默认医院
	chainCode, employeeLocalID, err := repository.QueryChainCodeAndLocalIDByPhone(phone)
	if err != nil {
		return err
	}

	if chainCode == "" {
		return errors.New("请设置默认医院")
	}

	// 2. 拿到db
	safeMap := common.NewSafeMap()
	db, err := safeMap.GetOrStore(chainCode)
	if err != nil {
		return err
	}

	tx, err := db.Begin()
	if err != nil {
		return err
	}

	_, err = tx.Exec(fmt.Sprintf("update c_outcharge set updater = %v,delflag=1 where id in (%v)", employeeLocalID, expendID))
	if err != nil {
		tx.Rollback()
		return err
	}
	_, err = tx.Exec(fmt.Sprintf("update c_outcharge_pay set updater = %v,delflag=1 where c_outcharge_id in (%v)", employeeLocalID, expendID))
	if err != nil {
		tx.Rollback()
		return err
	}
	_, err = tx.Exec(fmt.Sprintf("update c_cashflow set updater = %v,delflag=1 where delflag=0 and bussiness_type=8 and bussiness_id in (select id from c_outcharge_pay where c_outcharge_id in (%v) and delflag=1) ", employeeLocalID, expendID))
	if err != nil {
		tx.Rollback()
		return err
	}
	err = tx.Commit()
	if err != nil {
		tx.Rollback()
		return err
	}

	return nil
}
