package Adl200Impl

import (
	"fmt"
	"tgk-touch/internal/global"
	"tgk-touch/internal/library/ADL200"
	"time"
)

// ===== 时间读取 =====

// ReadYear 读取电表年份
func (a *Adl200Impl) ReadYear(commUid string, addr byte) (int, error) {
	read, err := ADL200.H0012.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	value := read[0]
	// 高字节=年 (如 0x07 表示 2007)
	year := int(byte(value >> 8))
	return year, nil
}

// ReadMonth 读取电表月份
func (a *Adl200Impl) ReadMonth(commUid string, addr byte) (int, error) {
	read, err := ADL200.H0012.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	value := read[0]
	// 低字节=月
	month := int(byte(value))
	return month, nil
}

// ReadDay 读取电表日期
func (a *Adl200Impl) ReadDay(commUid string, addr byte) (int, error) {
	read, err := ADL200.H0013.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	value := read[0]
	// 低字节=日
	day := int(byte(value))
	return day, nil
}

// ReadHour 读取电表小时
func (a *Adl200Impl) ReadHour(commUid string, addr byte) (int, error) {
	read, err := ADL200.H0013.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	value := read[0]
	// 高字节=时
	hour := int(byte(value >> 8))
	return hour, nil
}

// ReadMinute 读取电表分钟
func (a *Adl200Impl) ReadMinute(commUid string, addr byte) (int, error) {
	read, err := ADL200.H0014.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	value := read[0]
	// 低字节=分
	minute := int(byte(value))
	return minute, nil
}

// ReadSecond 读取电表秒数
func (a *Adl200Impl) ReadSecond(commUid string, addr byte) (int, error) {
	read, err := ADL200.H0014.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	value := read[0]
	// 高字节=秒
	second := int(byte(value >> 8))
	return second, nil
}

// ReadTime 读取电表完整时间
func (a *Adl200Impl) ReadTime(commUid string, addr byte) (time.Time, error) {
	// 读取各个时间组件
	year, err := a.ReadYear(commUid, addr)
	if err != nil {
		return time.Time{}, fmt.Errorf("读取年份失败: %v", err)
	}

	month, err := a.ReadMonth(commUid, addr)
	if err != nil {
		return time.Time{}, fmt.Errorf("读取月份失败: %v", err)
	}

	day, err := a.ReadDay(commUid, addr)
	if err != nil {
		return time.Time{}, fmt.Errorf("读取日期失败: %v", err)
	}

	hour, err := a.ReadHour(commUid, addr)
	if err != nil {
		return time.Time{}, fmt.Errorf("读取小时失败: %v", err)
	}

	minute, err := a.ReadMinute(commUid, addr)
	if err != nil {
		return time.Time{}, fmt.Errorf("读取分钟失败: %v", err)
	}

	second, err := a.ReadSecond(commUid, addr)
	if err != nil {
		return time.Time{}, fmt.Errorf("读取秒数失败: %v", err)
	}

	// 构建时间对象 (年份为 2 位数字，加 2000)
	loc, _ := time.LoadLocation("Local")
	t := time.Date(
		year+2000,
		time.Month(month),
		day,
		hour,
		minute,
		second,
		0,
		loc,
	)
	return t, nil
}

// ===== 电气参数读取 =====

// ReadVoltage 读取电压 (单相电表只有单相电压)
func (a *Adl200Impl) ReadVoltage(commUid string, addr byte) (totalVoltage, aVoltage, bVoltage, cVoltage float64, err error) {
	read, err := ADL200.H000B.Read(commUid, addr)
	if err != nil {
		return
	}
	// 单位: 0.1V
	aVoltage = float64(read[0]) * 0.1
	// ADL200 是单相电表，总电压即为 A 相电压
	totalVoltage = aVoltage
	return totalVoltage, aVoltage, bVoltage, cVoltage, err
}

// ReadElectricCurrent 读取电流 (单相电表只有单相电流)
func (a *Adl200Impl) ReadElectricCurrent(commUid string, addr byte) (totalElectricCurrent, aElectricCurrent, bElectricCurrent, cElectricCurrent float64, err error) {
	read, err := ADL200.H000C.Read(commUid, addr)
	if err != nil {
		return
	}
	// 单位: 0.01A
	aElectricCurrent = float64(read[0]) * 0.01
	totalElectricCurrent = aElectricCurrent
	return totalElectricCurrent, aElectricCurrent, bElectricCurrent, cElectricCurrent, err
}

// ReadPower 读取功率 (单相电表只有总有功功率)
func (a *Adl200Impl) ReadPower(commUid string, addr byte) (totalPower, aPower, bPower, cPower float64, err error) {
	read, err := ADL200.H000D.Read(commUid, addr)
	if err != nil {
		return
	}
	// 单位: 0.001kW
	totalPower = float64(read[0]) * 0.001
	aPower = totalPower
	return totalPower, aPower, bPower, cPower, err
}

// ReadTotalPower 读取总有功功率
func (a *Adl200Impl) ReadTotalPower(commUid string, addr byte) (totalPower float64, err error) {
	read, err := ADL200.H000D.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	// 单位: 0.001kW
	totalPower = float64(read[0]) * 0.001
	return totalPower, err
}

// ReadEnergy 读取电能 (4 字节数据，需要两个寄存器)
func (a *Adl200Impl) ReadEnergy(commUid string, addr byte) (totalEnergy, aEnergy, bEnergy, cEnergy float64, err error) {
	read, err := ADL200.H0068.Read(commUid, addr)
	if err != nil {
		return
	}
	// 高16位在前，低16位在后 (大端序)
	high := uint32(read[0])     // 高16位
	low := uint32(read[1])      // 低16位
	value := (high << 16) | low // 组合为32位整数
	// 单位: 0.01kWh
	totalEnergy = float64(value) * 0.01
	aEnergy = totalEnergy // 单相电表，A相电能即为总电能
	return totalEnergy, aEnergy, bEnergy, cEnergy, err
}

// ReadPowerFactor 读取功率因数 (单相电表)
func (a *Adl200Impl) ReadPowerFactor(commUid string, addr byte) (totalPf, aPf, bPf, cPf float64, err error) {
	read, err := ADL200.H0010.Read(commUid, addr)
	if err != nil {
		return
	}
	// 单位: 0.001
	aPf = float64(read[0]) * 0.001
	totalPf = aPf
	return totalPf, aPf, bPf, cPf, err
}

// ===== 其他读取 =====

// ReadMsgAddr 读取通信地址
func (a *Adl200Impl) ReadMsgAddr(commUid string, addr byte) (msgAddr byte, err error) {
	read, err := ADL200.H0015.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	value := read[0]
	// 高8位=通信地址 (0~254)
	msgAddr = byte(value >> 8)
	g.Log().Infof("ADL200 ReadMsgAddr raw: 0x%X, msgAddr: 0x%X (%d)", value, msgAddr, msgAddr)
	return msgAddr, nil
}

// ReadMainAddr 读取主控地址 (DL/T645 表号，暂不支持)
func (a *Adl200Impl) ReadMainAddr(commUid string, addr byte) (byte, error) {
	// ADL200 使用表号代替主控地址，此处返回通信地址作为占位
	return a.ReadMsgAddr(commUid, addr)
}

// ReadDailyFreezingTime 读取日冻结时间 (ADL200 不支持日冻结，返回默认)
func (a *Adl200Impl) ReadDailyFreezingTime(commUid string, addr byte) (dailyFreezingTime string, err error) {
	// ADL200 单相电表不支持日冻结时间设置
	return "00:00", nil
}

// ReadMonthlyFreezingTime 读取月冻结时间 (ADL200 不支持月冻结，返回默认)
func (a *Adl200Impl) ReadMonthlyFreezingTime(commUid string, addr byte) (day, hour string, err error) {
	// ADL200 单相电表不支持月冻结时间设置
	return "01", "00", nil
}

// ===== 额外的数据读取方法 =====

// ReadFrequency 读取电网频率
func (a *Adl200Impl) ReadFrequency(commUid string, addr byte) (frequency float64, err error) {
	read, err := ADL200.H0011.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	// 单位: 0.01Hz
	frequency = float64(read[0]) * 0.01
	return frequency, nil
}

// ReadReactivePower 读取无功功率
func (a *Adl200Impl) ReadReactivePower(commUid string, addr byte) (reactivePower float64, err error) {
	read, err := ADL200.H000E.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	// 单位: 0.001kvar
	reactivePower = float64(read[0]) * 0.001
	return reactivePower, nil
}

// ReadApparentPower 读取视在功率
func (a *Adl200Impl) ReadApparentPower(commUid string, addr byte) (apparentPower float64, err error) {
	read, err := ADL200.H000F.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	// 单位: 0.001kVA
	apparentPower = float64(read[0]) * 0.001
	return apparentPower, nil
}

// ReadCombinedEnergy 读取组合有功总电能
func (a *Adl200Impl) ReadCombinedEnergy(commUid string, addr byte) (energy float64, err error) {
	read, err := ADL200.H0000.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	high := uint32(read[0])
	low := uint32(read[1])
	value := (high << 16) | low
	// 单位: 0.01kWh
	energy = float64(value) * 0.01
	return energy, nil
}

// ReadReactiveEnergy 读取总无功电能
func (a *Adl200Impl) ReadReactiveEnergy(commUid string, addr byte) (energy float64, err error) {
	read, err := ADL200.H00B0.Read(commUid, addr)
	if err != nil {
		return 0, err
	}
	high := uint32(read[0])
	low := uint32(read[1])
	value := (high << 16) | low
	// 单位: 0.01kVarh
	energy = float64(value) * 0.01
	return energy, nil
}
