package repository

import (
	"database/sql"
	"errors"
	"fmt"
	"gin-vue-admin/common"
	"gin-vue-admin/models"
	"time"
)

func GetPayMealListRepository(phone string) (interface{}, error) {

	db, err := common.NewAccountConn()
	if err != nil {
		return nil, err
	}

	var chainID, hospitalID int

	err = db.QueryRow(`select m.id, w.hospital_main_id from employee_wx as w
join chain_main as m on m.chain_code = w.default_chain_code
	where employee_phone = ?`, phone).Scan(&chainID, &hospitalID)
	if err != nil {
		return nil, err
	}

	var isOpen int
	err = db.QueryRow(`select count(id) from b_doctor_hospital
	where delflag = 0 and chain_id = ? and hospital_id = ?`, chainID, hospitalID).Scan(&isOpen)
	if err != nil {
		return nil, err
	}

	sqlStr := `select id, ifnull(convert(money / 1000, decimal(11,2)), 0),
year, month, day, meal_type, description
from con_meal_b_doctor
where delflag = 0`

	if isOpen != 0 {
		sqlStr += " and meal_type = 0 "
	}

	rows, err := db.Query(sqlStr)
	if err != nil {
		return nil, err
	}

	response := make([]models.PayMealList, 0)

	for rows.Next() {
		var temp models.PayMealList
		err = rows.Scan(&temp.ID, &temp.Money, &temp.Year, &temp.Month, &temp.Day, &temp.MealType, &temp.Description)
		if err != nil {
			return nil, err
		}
		response = append(response, temp)
	}

	return response, nil
}

func QueryUserWxInfo(db *sql.DB, phone string) (int, int, string, error) {

	var chainID, hospitalID int
	var openID string

	err := db.QueryRow(`select m.id, w.hospital_main_id, w.wx_open_id from employee_wx as w
join chain_main as m on m.chain_code = w.default_chain_code
	where employee_phone = ?`, phone).Scan(&chainID, &hospitalID, &openID)
	switch {
	case err == sql.ErrNoRows:
		return 0, 0, "", errors.New("未查到此医院")
	case err != nil:
		return 0, 0, "", err
	}

	return chainID, hospitalID, openID, nil
}

func QueryMealInfo(db *sql.DB, mealID int) (*models.PayMealList, error) {

	sqlStr := `select id, ifnull(convert(money / 1000, decimal(11,2)), 0),
year, month, day, description
from con_meal_b_doctor
where id = ?`

	r := new(models.PayMealList)
	err := db.QueryRow(sqlStr, mealID).Scan(&r.ID, &r.Money, &r.Year, &r.Month, &r.Day, &r.Description)
	return r, err
}

func InsertBDoctorBill(tx *sql.Tx, chainID, hospitalID int, m *models.PayMealList) (int64, error) {

	insertSQL := `insert b_doctor_bill set chain_id = ?, hospital_id = ?, pay_type = ?, paymoney = ?, 
commodity_describe = ?, commodity_detail = ?, year = ?, month = ?, day = ?`

	result, err := tx.Exec(insertSQL, chainID, hospitalID, 2, m.Money*1000,
		"医生端小程序 套餐购买", "医生端小程序 套餐购买 "+m.Description, m.Year, m.Month, m.Day)
	if err != nil {
		return 0, err
	}

	billID, err := result.LastInsertId()
	if err != nil {
		return 0, err
	}

	return billID, nil
}

func UpdateBDoctorBill(tx *sql.Tx, billCode string, billID int64) (interface{}, error) {

	updateSQL := `update b_doctor_bill set payment_order_code = ? where id = ?`
	billResult, err := tx.Exec(updateSQL, billCode, billID)
	if err != nil {
		_ = tx.Rollback()
		return nil, err
	}
	_, err = billResult.RowsAffected()
	if err != nil {
		_ = tx.Rollback()
		return nil, err
	}

	return nil, nil
}

// 根据订单号 查询订单相关信息
func QueryBDoctorBillInfo(db *sql.DB, outTradeNo string) (*models.BDoctorBill, error) {

	var b models.BDoctorBill
	err := db.QueryRow(`select id, chain_id, hospital_id, result_code, year, month, day from b_doctor_bill
where payment_order_code = ?`, outTradeNo).Scan(&b.ID, &b.ChainID, &b.HospitalID, &b.ResultCode, &b.Year, &b.Month, &b.Day)
	switch {
	case err == sql.ErrNoRows:
		return nil, errors.New("订单不存在")
	case err != nil:
		return nil, err
	}
	return &b, nil
}

func UpdateBDoctorBillBySuccess(tx *sql.Tx, billID int) error {

	updateSQL := `update b_doctor_bill set result_code = 1 where id = ?`
	billResult, err := tx.Exec(updateSQL, billID)
	if err != nil {
		return err
	}
	_, err = billResult.RowsAffected()
	if err != nil {
		return err
	}

	return nil
}

func UpdateBDoctorHospital(tx *sql.Tx, p *models.BDoctorBill) error {

	var is int
	err := tx.QueryRow(`select count(*) from b_doctor_hospital
where chain_id = ? and hospital_id = ?`, p.ChainID, p.HospitalID).Scan(&is)
	if err != nil {
		return err
	}

	// 新增
	if is == 0 {

		now := time.Now()
		startTime := now.Format("2006-01-02 15:04:05")
		endTime := now.AddDate(p.Year, p.Month, p.Day).Format("2006-01-02 15:04:05")
		result, err := tx.Exec(`insert b_doctor_hospital set chain_id = ?, hospital_id = ?, is_on_trial = 1, start_time = ?, end_time = ?`,
			p.ChainID, p.HospitalID, startTime, endTime)
		if err != nil {
			return err
		}
		bDoctorHospitalID, err := result.LastInsertId()
		if err != nil {
			return err
		}

		result, err = tx.Exec(`insert b_doctor_hospital_detail set b_doctor_hospital_id = ?, start_time = ?, end_time = ?, is_free = 1`,
			bDoctorHospitalID, startTime, endTime)
		if err != nil {
			return err
		}
		_, err = result.LastInsertId()
		if err != nil {
			return err
		}

		return nil
	} else { // 更新

		var id int
		var endTime string

		err = tx.QueryRow(`select id, end_time from b_doctor_hospital
where chain_id = ? and hospital_id = ?`, p.ChainID, p.HospitalID).Scan(&id, &endTime)
		if err != nil {
			return err
		}

		end, err := time.Parse("2006-01-02 15:04:05", endTime)
		if err != nil {
			return err
		}

		//newEndTime := end.AddDate(p.Year, p.Month, p.Day).Format("2006-01-02 15:04:05")
		var newEndTime time.Time
		if time.Until(end).Hours() <= 0 {
			fmt.Println("新时间")
			newEndTime = time.Now().AddDate(p.Year, p.Month, p.Day)
		} else {
			fmt.Println("在老时间上面加")
			newEndTime = end.AddDate(p.Year, p.Month, p.Day)
		}

		fmt.Println("year: ", p.Year)
		fmt.Println("month: ", p.Month)
		fmt.Println("day: ", p.Day)
		fmt.Println("endTime: ", endTime)
		fmt.Println("newEndTime: ", newEndTime.Format("2006-01-02 15:04:05"))
		result, err := tx.Exec(`update b_doctor_hospital set is_on_trial = 1, end_time = ? where id = ?`,
			newEndTime, id)
		if err != nil {
			return err
		}
		_, err = result.RowsAffected()
		if err != nil {
			return err
		}

		result, err = tx.Exec(`insert b_doctor_hospital_detail set b_doctor_hospital_id = ?, start_time = ?, end_time = ?, is_free = 1`,
			id, endTime, newEndTime)
		if err != nil {
			return err
		}
		_, err = result.LastInsertId()
		if err != nil {
			return err
		}

		return nil
	}
}

func QueryDoctorState(db *sql.DB, chainID, hospitalID int) (interface{}, error) {

	var isOnTrial int
	var endTime string
	var r models.OpenState

	err := db.QueryRow(`select is_on_trial, end_time from b_doctor_hospital
where chain_id = ? and hospital_id = ?`, chainID, hospitalID).Scan(&isOnTrial, &endTime)
	switch {
	case err == sql.ErrNoRows:
		r.State = 0
		return r, nil
	case err != nil:
		return nil, err
	}

	r.ExpireTime = endTime

	if isOnTrial == 0 {
		r.State = 1
	} else if isOnTrial == 1 {
		r.State = 2
	}

	now := time.Now()
	endT, err := time.Parse("2006-01-02 15:04:05", endTime)
	if err != nil {
		return nil, err
	}

	hours := endT.Sub(now).Hours()
	if hours <= 0 {
		r.IsExpire = 1
	}

	if hours >= 720 {
		r.AboutToExpire = 1
	}

	return r, nil
}

func QueryBillState(db *sql.DB, code string) (interface{}, error) {

	var r models.BillState
	err := db.QueryRow(`select result_code from b_doctor_bill where payment_order_code = ?`, code).Scan(&r.State)
	switch {
	case err == sql.ErrNoRows:
		return r, errors.New("未查到订单")
	case err != nil:
		return nil, err
	}

	return r, nil
}

func OnTrail(db *sql.DB, chainID, hospitalID int, p *models.PayMealList) (interface{}, error) {

	now := time.Now()
	startTime := now.Format("2006-01-02 15:04:05")
	endTime := now.AddDate(0, 0, p.Day).Format("2006-01-02 15:04:05")

	tx, err := db.Begin()
	if err != nil {
		return nil, err
	}
	result, err := tx.Exec(`insert b_doctor_hospital set chain_id = ?, hospital_id = ?, is_on_trial = 0, start_time = ?, end_time = ?`,
		chainID, hospitalID, startTime, endTime)
	if err != nil {
		tx.Rollback()
		return nil, err
	}
	bDoctorHospitalID, err := result.LastInsertId()
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	result, err = tx.Exec(`insert b_doctor_hospital_detail set b_doctor_hospital_id = ?, start_time = ?, end_time = ?, is_free = 0`,
		bDoctorHospitalID, startTime, endTime)
	if err != nil {
		return nil, err
	}
	_, err = result.LastInsertId()
	if err != nil {
		return nil, err
	}

	_ = tx.Commit()

	return nil, nil
}
