package fuiou

import (
	"encoding/xml"
	"fmt"
	"net/url"
	"strings"
)

// ParseNotify 解析回调通知（不验签）
// 用于在验签前提取订单号以确定使用哪套支付配置
func ParseNotify(rawBody []byte) (*NotifyRequest, error) {
	content := string(rawBody)
	if strings.HasPrefix(content, "req=") {
		content = content[4:]
	}
	decoded, err := url.QueryUnescape(content)
	if err != nil {
		return nil, fmt.Errorf("URL 解码回调数据失败: %w", err)
	}
	utf8Bytes, err := GBKToUTF8([]byte(decoded))
	if err != nil {
		return nil, fmt.Errorf("GBK 转 UTF-8 失败: %w", err)
	}
	utf8Str := strings.Replace(string(utf8Bytes), `encoding="GBK"`, `encoding="UTF-8"`, 1)
	var notify NotifyRequest
	if err := xml.Unmarshal([]byte(utf8Str), &notify); err != nil {
		return nil, fmt.Errorf("XML 解析回调数据失败: %w", err)
	}
	return &notify, nil
}

// VerifyNotify 验证回调通知并解析数据
// rawBody: 原始请求 body（可能包含 req= 前缀的 URL 编码 GBK XML）
func (c *Client) VerifyNotify(rawBody []byte) (*NotifyRequest, error) {
	content := string(rawBody)

	// 处理 req= 前缀（富友回调可能以 form 格式发送）
	if strings.HasPrefix(content, "req=") {
		content = content[4:]
	}

	// URL 解码
	decoded, err := url.QueryUnescape(content)
	if err != nil {
		return nil, fmt.Errorf("URL 解码回调数据失败: %w", err)
	}

	// GBK → UTF-8
	utf8Bytes, err := GBKToUTF8([]byte(decoded))
	if err != nil {
		return nil, fmt.Errorf("GBK 转 UTF-8 失败: %w", err)
	}

	// 替换编码声明
	utf8Str := strings.Replace(string(utf8Bytes), `encoding="GBK"`, `encoding="UTF-8"`, 1)

	// XML 解析
	var notify NotifyRequest
	if err := xml.Unmarshal([]byte(utf8Str), &notify); err != nil {
		return nil, fmt.Errorf("XML 解析回调数据失败: %w", err)
	}

	// 验证签名
	if err := c.Verify(&notify, notify.Sign); err != nil {
		return nil, fmt.Errorf("回调签名验证失败: %w", err)
	}

	// 检查结果码
	if notify.ResultCode != "000000" {
		return &notify, fmt.Errorf("回调结果非成功: %s - %s", notify.ResultCode, notify.ResultMsg)
	}

	return &notify, nil
}

// BuildNotifySuccessResponse 构建成功响应（GBK 编码的 XML）
func BuildNotifySuccessResponse() []byte {
	return buildNotifyResponse("000000", "success")
}

// BuildNotifyFailResponse 构建失败响应（GBK 编码的 XML）
func BuildNotifyFailResponse(msg string) []byte {
	return buildNotifyResponse("999999", msg)
}

// buildNotifyResponse 构建回调响应 XML（GBK 编码）
func buildNotifyResponse(code, msg string) []byte {
	resp := NotifyResponse{
		ResultCode: code,
		ResultMsg:  msg,
	}

	xmlBytes, err := xml.Marshal(resp)
	if err != nil {
		return []byte(`<?xml version="1.0" encoding="GBK"?><xml><result_code>999999</result_code><result_msg>internal error</result_msg></xml>`)
	}

	xmlStr := `<?xml version="1.0" encoding="GBK"?>` + string(xmlBytes)

	gbkBytes, err := utf8ToGBK([]byte(xmlStr))
	if err != nil {
		return []byte(xmlStr)
	}

	return gbkBytes
}
