
package main

import (
	"encoding/hex"
	"errors"
	"fmt"
	"github.com/btcsuite/btcd/btcutil"
	"github.com/btcsuite/btcd/chaincfg"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcd/wire"
	"github.com/btcsuite/btcwallet/wallet/txrules"
)

// 前端请求参数结构
type InscriptionTransferRequest struct {
	FromAddress   string   `json:"fromAddress"`
	ToAddress     string   `json:"toAddress"`
	Ticker        string   `json:"ticker"` // 代币符号FFFF
	Amount        uint64   `json:"amount"` // 转移数量
	FeeRate       uint64   `json:"feeRate"` // sat/byte
	UTXOs         []string `json:"utxos"`  // 铭文UTXO的txid:vout
}

// PSBT构造响应
type PSBTResponse struct {
	UnsignedPSBT string   `json:"unsignedPSBT"`
	UsedUTXOs    []string `json:"usedUTXOs"`
	ChangeAmount int64    `json:"changeAmount"` // 找零金额
}

// 核心处理函数
func BuildInscriptionPSBT(req InscriptionTransferRequest) (*PSBTResponse, error) {
	// 1. 参数校验
	if err := validateRequest(req); err != nil {
		return nil, err
	}

	// 2. 获取UTXO数据（实际应从区块链节点获取）
	utxos, err := fetchInscriptionUTXOs(req.FromAddress, req.Ticker)
	if err != nil {
		return nil, err
	}

	// 3. 选择足够金额的UTXO组合
	selectedUTXOs, changeAmount := selectUTXOs(utxos, req.Amount)
	if len(selectedUTXOs) == 0 {
		return nil, errors.New("insufficient inscription balance")
	}

	// 4. 构造PSBT交易
	psbt, err := constructPSBTTx(selectedUTXOs, req.ToAddress, req.FromAddress, 
		req.Amount, changeAmount, req.FeeRate)
	if err != nil {
		return nil, err
	}

	return &PSBTResponse{
		UnsignedPSBT: psbt,
		UsedUTXOs:    getUTXOIdentifiers(selectedUTXOs),
		ChangeAmount: changeAmount,
	}, nil
}

// UTXO选择算法（简化版）
func selectUTXOs(utxos []InscriptionUTXO, amount uint64) ([]InscriptionUTXO, int64) {
	var selected []InscriptionUTXO
	var total uint64

	for _, utxo := range utxos {
		if utxo.Amount >= amount {
			return []InscriptionUTXO{utxo}, int64(utxo.Amount - amount)
		}
		selected = append(selected, utxo)
		total += utxo.Amount
		if total >= amount {
			return selected, int64(total - amount)
		}
	}
	return nil, 0
}

// PSBT交易构造
func constructPSBTTx(utxos []InscriptionUTXO, toAddr, fromAddr string, 
	amount uint64, change int64, feeRate uint64) (string, error) {

	msgTx := wire.NewMsgTx(wire.TxVersion)
	
	// 添加输入
	for _, utxo := range utxos {
		hash, _ := chainhash.NewHashFromStr(utxo.TxID)
		outPoint := wire.NewOutPoint(hash, utxo.Vout)
		txIn := wire.NewTxIn(outPoint, nil, nil)
		msgTx.AddTxIn(txIn)
	}

	// 添加输出（接收方）
	toScript, _ := btcutil.DecodeAddress(toAddr, &chaincfg.MainNetParams)
	msgTx.AddTxOut(wire.NewTxOut(int64(amount), toScript.ScriptAddress()))

	// 添加找零输出
	if change > 0 {
		fromScript, _ := btcutil.DecodeAddress(fromAddr, &chaincfg.MainNetParams)
		msgTx.AddTxOut(wire.NewTxOut(change, fromScript.ScriptAddress()))
	}

	// 转换为PSBT
	psbt, err := psbt.NewFromUnsignedTx(msgTx)
	if err != nil {
		return "", err
	}

	// 返回Base64编码的PSBT
	return psbt.B64Encode()
}
