package connect

import (
	"context"
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"math/big"
	"net"
	"time"

	"github.com/quic-go/quic-go"
	"go.uber.org/zap"
)

// QUICListener QUIC 监听器
type QUICListener struct {
	listener *quic.Listener
}

// NewQUICListener 创建 QUIC 监听器
func NewQUICListener(addr string, logger *zap.Logger) (*QUICListener, error) {
	// 生成自签名证书（用于测试）
	cert, err := generateSelfSignedCert()
	if err != nil {
		return nil, fmt.Errorf("生成证书失败：%w", err)
	}

	tlsConf := &tls.Config{
		Certificates: []tls.Certificate{cert},
		NextProtos:   []string{"meshray-quic"},
	}

	udpAddr, err := net.ResolveUDPAddr("udp", addr)
	if err != nil {
		return nil, err
	}

	udpConn, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		return nil, err
	}

	listener, err := quic.Listen(udpConn, tlsConf, nil)
	if err != nil {
		return nil, fmt.Errorf("创建 QUIC 监听器失败：%w", err)
	}

	logger.Info("QUIC 监听器已启动", zap.String("addr", addr))

	return &QUICListener{
		listener: listener,
	}, nil
}

// Accept 接受 QUIC 连接
func (l *QUICListener) Accept(ctx context.Context) (*quic.Conn, error) {
	return l.listener.Accept(ctx)
}

// Close 关闭监听器
func (l *QUICListener) Close() error {
	return l.listener.Close()
}

// QUICClient QUIC 客户端
type QUICClient struct {
	servers []string
	logger  *zap.Logger
}

// NewQUICClient 创建 QUIC 客户端
func NewQUICClient(servers []string, logger *zap.Logger) *QUICClient {
	return &QUICClient{
		servers: servers,
		logger:  logger,
	}
}

// Connect 建立 QUIC 连接
func (c *QUICClient) Connect(ctx context.Context) (net.Conn, error) {
	if len(c.servers) == 0 {
		return nil, fmt.Errorf("未配置 QUIC 服务器")
	}

	// 使用不安全的 TLS 配置（跳过证书验证，用于测试）
	tlsConf := &tls.Config{
		InsecureSkipVerify: true,
		NextProtos:         []string{"meshray-quic"},
	}

	// 尝试连接第一个服务器
	for _, server := range c.servers {
		_, err := net.ResolveUDPAddr("udp", server)
		if err != nil {
			c.logger.Warn("解析 QUIC 服务器地址失败",
				zap.String("server", server),
				zap.Error(err))
			continue
		}

		var conn *quic.Conn
		conn, err = quic.DialAddr(ctx, server, tlsConf, nil)
		if err == nil {
			c.logger.Info("QUIC 连接已建立",
				zap.String("server", server),
				zap.String("local_addr", conn.LocalAddr().String()))
			return newQUICConn(conn), nil
		}

		c.logger.Warn("QUIC 连接失败",
			zap.String("server", server),
			zap.Error(err))
	}

	return nil, fmt.Errorf("所有 QUIC 服务器连接失败")
}

// quicConn QUIC 连接包装器（实现 net.Conn）
type quicConn struct {
	conn   *quic.Conn   // quic-go v0.59.0 使用 *quic.Conn
	stream *quic.Stream // 使用 *quic.Stream
}

// newQUICConn 创建 QUIC 连接包装器
func newQUICConn(conn *quic.Conn) *quicConn {
	return &quicConn{
		conn: conn,
	}
}

// OpenStream 打开流
func (c *quicConn) OpenStream() error {
	stream, err := c.conn.OpenStreamSync(context.Background())
	if err != nil {
		return err
	}
	c.stream = stream
	return nil
}

// Read 实现 net.Conn
func (c *quicConn) Read(b []byte) (n int, err error) {
	if c.stream == nil {
		stream, err := c.conn.OpenStreamSync(context.Background())
		if err != nil {
			return 0, err
		}
		c.stream = stream
	}
	return c.stream.Read(b)
}

// Write 实现 net.Conn
func (c *quicConn) Write(b []byte) (n int, err error) {
	if c.stream == nil {
		stream, err := c.conn.OpenStreamSync(context.Background())
		if err != nil {
			return 0, err
		}
		c.stream = stream
	}
	return c.stream.Write(b)
}

// Close 实现 net.Conn
func (c *quicConn) Close() error {
	if c.stream != nil {
		c.stream.Close()
	}
	return c.conn.CloseWithError(0, "closed")
}

// LocalAddr 实现 net.Conn
func (c *quicConn) LocalAddr() net.Addr {
	return c.conn.LocalAddr()
}

// RemoteAddr 实现 net.Conn
func (c *quicConn) RemoteAddr() net.Addr {
	return c.conn.RemoteAddr()
}

// SetDeadline 实现 net.Conn
func (c *quicConn) SetDeadline(t time.Time) error {
	if c.stream != nil {
		return (*c.stream).SetDeadline(t)
	}
	return nil
}

// SetReadDeadline 实现 net.Conn
func (c *quicConn) SetReadDeadline(t time.Time) error {
	if c.stream != nil {
		return (*c.stream).SetReadDeadline(t)
	}
	return nil
}

// SetWriteDeadline 实现 net.Conn
func (c *quicConn) SetWriteDeadline(t time.Time) error {
	if c.stream != nil {
		return (*c.stream).SetWriteDeadline(t)
	}
	return nil
}

// generateSelfSignedCert 生成自签名证书（仅用于测试）
func generateSelfSignedCert() (tls.Certificate, error) {
	// 生成私钥
	priv, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		return tls.Certificate{}, err
	}

	// 生成证书模板
	template := x509.Certificate{
		SerialNumber: big.NewInt(1),
		NotBefore:    time.Now(),
		NotAfter:     time.Now().Add(365 * 24 * time.Hour),
		DNSNames:     []string{"localhost"},
	}

	// 自签名
	certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
	if err != nil {
		return tls.Certificate{}, err
	}

	// 编码证书和私钥
	certPEM := pem.EncodeToMemory(&pem.Block{
		Type:  "CERTIFICATE",
		Bytes: certDER,
	})

	keyPEM := pem.EncodeToMemory(&pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: x509.MarshalPKCS1PrivateKey(priv),
	})

	// 加载证书
	return tls.X509KeyPair(certPEM, keyPEM)
}

// NewTURNFactoryQUIC 创建 QUIC TURN 工厂（用于 9 层降级策略）
// 注意：当前版本暂不启用 QUIC 支持，返回 nil
func NewTURNFactoryQUIC(servers []string, username, password string, logger *zap.Logger) *TURNFactory {
	logger.Warn("QUIC 传输模式暂不支持，已跳过")
	return nil // 暂时返回 nil，未来实现 QUIC 支持时再完善
}
