package uhf

import (
	"errors"
	"fmt"
	"net"
	"time"
)

type TCPReader struct {
	IP          string
	Port        int
	conn        net.Conn
	isConnected bool
	buffer      []byte // 内部拼包缓冲区（关键修复）
}

// 实现 Reader 接口的继电器方法（不再panic）
func (t *TCPReader) CloseRelay1(validTime byte) error {
	frame := buildRelayFrame(0x0077, 1, RELAY_OP_CLOSE, validTime)
	_, err := t.SendAndRecv(frame)
	return err
}

func (t *TCPReader) ReleaseRelay1() error {
	frame := buildRelayFrame(0x0077, 1, RELAY_OP_RELEASE, 0)
	_, err := t.SendAndRecv(frame)
	return err
}

func (t *TCPReader) CloseRelay2(validTime byte) error {
	frame := buildRelayFrame(0x0078, 2, RELAY_OP_CLOSE, validTime)
	_, err := t.SendAndRecv(frame)
	return err
}

func (t *TCPReader) ReleaseRelay2() error {
	frame := buildRelayFrame(0x0078, 2, RELAY_OP_RELEASE, 0)
	_, err := t.SendAndRecv(frame)
	return err
}

func NewTCPReader(ip string, port int) *TCPReader {
	return &TCPReader{
		IP:   ip,
		Port: port,
	}
}

func (t *TCPReader) Connect() error {
	addr := net.JoinHostPort(t.IP, fmt.Sprintf("%d", t.Port))
	conn, err := net.DialTimeout("tcp", addr, 5*time.Second)
	if err != nil {
		t.isConnected = false
		return err
	}
	t.conn = conn
	t.isConnected = true
	return nil
}

func (t *TCPReader) Disconnect() error {
	if t.conn != nil {
		_ = t.conn.Close()
	}
	t.isConnected = false
	t.buffer = nil
	return nil
}

func (t *TCPReader) IsConnected() bool {
	return t.isConnected
}

func (t *TCPReader) SendData(data []byte) error {
	if !t.isConnected {
		return errors.New("TCP未连接")
	}
	_, err := t.conn.Write(data)
	if err != nil {
		t.isConnected = false
	}
	return err
}

// ==============================
// 🔥 关键修复：TCP 自动拼包，返回完整25字节帧
// ==============================
func (t *TCPReader) ReadData() ([]byte, error) {
	if !t.isConnected {
		return nil, errors.New("TCP未连接")
	}

	// 读超时，防止永久阻塞
	t.conn.SetReadDeadline(time.Now().Add(3 * time.Second))

	buf := make([]byte, 1024)
	n, err := t.conn.Read(buf)
	if err != nil {
		t.isConnected = false
		return nil, err
	}

	// 加入缓冲区
	t.buffer = append(t.buffer, buf[:n]...)

	// 找完整帧：0xCF 开头 + 25字节
	for len(t.buffer) >= 25 {
		if t.buffer[0] == 0xCF {
			frame := t.buffer[:25]
			t.buffer = t.buffer[25:]
			return frame, nil
		} else {
			t.buffer = t.buffer[1:]
		}
	}

	return nil, errors.New("等待完整帧")
}

func (t *TCPReader) SendAndRecv(data []byte) ([]byte, error) {
	if err := t.SendData(data); err != nil {
		return nil, err
	}
	t.conn.SetReadDeadline(time.Now().Add(3 * time.Second))
	return t.ReadData()
}
