package printer

import (
	"fmt"
	"strings"

	"github.com/xgadget-lab/nexttrace/ipgeo"

	"github.com/xgadget-lab/nexttrace/trace"

	"github.com/fatih/color"
	"github.com/rodaine/table"
)

type rowData struct {
	Hop      string
	IP       string
	Latency  string
	Asnumber string
	Country  string
	Prov     string
	City     string
	District string
	Owner    string
}

func TracerouteTablePrinter(res *trace.Result) {
	// 初始化表格
	tbl := New()
	for _, hop := range res.Hops {
		for k, h := range hop {
			data := tableDataGenerator(h)
			if k > 0 {
				data.Hop = ""
			}
			if data.Country == "" && data.Prov == "" && data.City == "" {
				tbl.AddRow(data.Hop, data.IP, data.Latency, data.Asnumber, "", data.Owner)
			} else {
				if data.City != "" {
					tbl.AddRow(data.Hop, data.IP, data.Latency, data.Asnumber, data.City+", "+data.Prov+", "+data.Country, data.Owner)
				} else if data.Prov != "" {
					tbl.AddRow(data.Hop, data.IP, data.Latency, data.Asnumber, data.Prov+", "+data.Country, data.Owner)
				} else {
					tbl.AddRow(data.Hop, data.IP, data.Latency, data.Asnumber, data.Country, data.Owner)
				}

			}
		}
	}
	fmt.Print("\033[H\033[2J")
	// 打印表格
	tbl.Print()
}

func New() table.Table {
	// 初始化表格
	headerFmt := color.New(color.FgGreen, color.Underline).SprintfFunc()
	columnFmt := color.New(color.FgYellow).SprintfFunc()

	tbl := table.New("Hop", "IP", "Lantency", "ASN", "Location", "Owner")
	tbl.WithHeaderFormatter(headerFmt).WithFirstColumnFormatter(columnFmt)
	return tbl
}

func tableDataGenerator(h trace.Hop) *rowData {
	if h.Address == nil {
		return &rowData{
			Hop: fmt.Sprint(h.TTL),
			IP:  "*",
		}
	} else {
		lantency := fmt.Sprintf("%.2fms", h.RTT.Seconds()*1000)
		IP := h.Address.String()

		if strings.HasPrefix(IP, "9.") {
			return &rowData{
				Hop:     fmt.Sprint(h.TTL),
				IP:      IP,
				Latency: lantency,
				Country: "LAN Address",
				Prov:    "",
				Owner:   "",
			}
		} else if strings.HasPrefix(IP, "11.") {
			return &rowData{
				Hop:     fmt.Sprint(h.TTL),
				IP:      IP,
				Latency: lantency,
				Country: "LAN Address",
				Prov:    "",
				Owner:   "",
			}
		}

		if h.Hostname != "" {
			IP = fmt.Sprint(h.Hostname, " (", IP, ") ")
		}

		if h.Geo == nil {
			h.Geo = &ipgeo.IPGeoData{}
		}

		r := &rowData{
			Hop:      fmt.Sprint(h.TTL),
			IP:       IP,
			Latency:  lantency,
			Asnumber: h.Geo.Asnumber,
			Country:  h.Geo.CountryEn,
			Prov:     h.Geo.ProvEn,
			City:     h.Geo.CityEn,
			District: h.Geo.District,
			Owner:    h.Geo.Owner,
		}

		if h.Geo == nil {
			return r
		}

		if h.Geo.Owner == "" {
			h.Geo.Owner = h.Geo.Isp
		}
		r.Asnumber = h.Geo.Asnumber
		r.Country = h.Geo.CountryEn
		r.Prov = h.Geo.ProvEn
		r.City = h.Geo.CityEn
		r.District = h.Geo.District
		r.Owner = h.Geo.Owner
		return r
	}
}
