package geoIp

import (
	"encoding/json"
	"fmt"
	"log"
	"net"
	"os"
	"path/filepath"

	"github.com/oschwald/geoip2-golang"
	"github.com/gffice/runproxypool/config"
)

var GeoIpDB GeoIP

func InitGeoIpDB() error {
	parentPath := config.ResourceRoot()
	geodbPath := "assets/GeoLite2-City.mmdb"
	flagsPath := "assets/flags.json"
	geodb := filepath.Join(parentPath, geodbPath)
	flags := filepath.Join(parentPath, flagsPath)
	// åˆ¤æ–­æ–‡ä»¶æ˜¯å�¦å­˜åœ¨
	_, err := os.Stat(geodb)
	if err != nil && os.IsNotExist(err) {
		if err != nil {
			log.Println("æ–‡ä»¶ä¸�å­˜åœ¨, è¯·è‡ªè¡Œä¸‹è½½ Geoip2 City åº“, å¹¶ä¿�å­˜åœ¨", geodb)
			panic(err)
		}
		GeoIpDB = NewGeoIP(geodb, flags)
	}
	GeoIpDB = NewGeoIP(geodb, flags)
	return nil
}

// GeoIP2
type GeoIP struct {
	db       *geoip2.Reader
	emojiMap map[string]string
}

type CountryEmoji struct {
	Code  string `json:"code"`
	Emoji string `json:"emoji"`
}

// new geoip from db file
func NewGeoIP(geodb, flags string) (geoip GeoIP) {
	// è¿�è¡Œåˆ°è¿™é‡Œæ—¶geodbå�ªèƒ½ä¸ºå­˜åœ¨
	db, err := geoip2.Open(geodb)
	if err != nil {
		log.Fatal(err)
	}
	geoip.db = db

	_, err = os.Stat(flags)
	if err != nil && os.IsNotExist(err) {
		log.Println("flags æ–‡ä»¶ä¸�å­˜åœ¨, è¯·è‡ªè¡Œä¸‹è½½ flags.json, å¹¶ä¿�å­˜åœ¨ ", flags)
		os.Exit(1)
	} else {
		data, err := os.ReadFile(flags)
		if err != nil {
			log.Fatal(err)
			return
		}
		var countryEmojiList = make([]CountryEmoji, 0)
		err = json.Unmarshal(data, &countryEmojiList)
		if err != nil {
			log.Fatalln(err.Error())
			return
		}

		emojiMap := make(map[string]string)
		for _, i := range countryEmojiList {
			emojiMap[i.Code] = i.Emoji
		}
		geoip.emojiMap = emojiMap
	}
	return
}

// find ip info
func (g GeoIP) Find(ipORdomain string) (ip, country string, err error) {
	ips, err := net.LookupIP(ipORdomain)
	if err != nil {
		return "", "", err
	}
	ip = ips[0].String()

	var record *geoip2.City
	record, err = g.db.City(ips[0])
	if err != nil {
		return
	}
	countryIsoCode := record.Country.IsoCode
	emoji, found := g.emojiMap[countryIsoCode]
	if found {
		country = fmt.Sprintf("%v%v", emoji, countryIsoCode)
	} else {
		country = "ğŸ��ZZ"
	}
	return ip, country, err
}
