package ext

import (
	"github.com/go-ego/gse"
	qu "qfw/util"
	ul "util"
)
type ExtractTask struct {
	ProvinceMap          map[string]string    //省全称简称(key:浙江省 val:浙江)
	ProvinceBriefMap     map[string]*Province //省简称对应的省信息(key:浙江 val:&Province{})
	CityMap              map[string]string    //市全称简称(key:杭州市 val:杭州)
	CityBriefMap         map[string]*City     //市简称对应的市信息(key:杭州 val:&City{})
	CityFullMap          map[string]*City     //市全称对应的市信息(key:杭州市 val:&City{})
	DistrictCityMap      map[string]*City
	NewDistrictCityMap   map[string][]*City            //区或县全称对应的city(全国有相同名称的区或县,这里对应的city用slice)
	DistrictSimAndAll    map[string]string             //区或县(key:简称 val:全称)
	NewDistrictSimAndAll map[string][]map[string]*City //区或县(key:简称 val:  相同简称的区全称:所在市)
	StreetDistrictMap    map[string]*District          //街道对应的区或县
	NewStreetDistrictMap map[string][]*District        //街道全称对应的区或县
	CommunityDistrictMap map[string][]*District        //村、居委会对应的区或县
	ProvinceAllGet       *DFA                       //省全称
	ProvinceSimGet       *DFA                       //省简称
	CityAllGet           *DFA                       //市全称
	CitySimGet           *DFA                       //市简称
	DistrictAllGet       *DFA                       //区或县全称
	DistrictSimGet       *DFA                       //区或县简称
	StreetGet            *DFA                       //街道

	Trie_Full_Province  *Trie       //省全称 省、直辖市、自治区
	Trie_Full_City      *Trie       //市全称 地级市
	Trie_Full_District  *Trie       //县全称 市辖区、县（旗）、县级市、自治县（自治旗）、特区、林区
	Trie_Full_Street    *Trie       //街道、乡镇全称  镇、乡、民族乡、县辖区、街道
	Trie_Full_Community *Trie       //村/委员会全称  村、居委会
	Trie_Sim_Province   *Trie       //省简称
	Trie_Sim_City       *Trie       //市简称
	Trie_Sim_District   *Trie       //县简称
	Trie_Fulls          []*Trie     //所有全称
	Trie_Sims           []*Trie     //所有简称
	Seg_PCD             *gse.Segmenter //分词
	Seg_SV              *gse.Segmenter //分词

}



func InitProvincesx() []map[string]interface{} {
	defer qu.Catch()
	provinces := make([]map[string]interface{}, 0)
	provinces,_ = ul.ExtMgo.Find(ul.ExtColl,map[string]interface{}{
		"Remarks": nil,
	},nil,nil)
	return provinces
}



func (e *ExtractTask) InitCityInfo() {
	defer qu.Catch()
	e.InitVar() //初始化变量
	//初始化省信息
	alldata := InitProvincesx()
	fnx := make([]map[string]interface{}, 0)
	citys_maps := make(map[string][]map[string]interface{}, 0)
	districts_maps := make(map[string]map[string][]map[string]interface{}, 0)
	towns_maps := make(map[string]map[string]map[string][]map[string]interface{}, 0)
	jwhs_maps := make(map[string]map[string]map[string]map[string][]map[string]interface{}, 0)
	for _, v := range alldata {
		codenum := len(v["code"].(string))
		province := qu.ObjToString(v["province"])
		city := qu.ObjToString(v["city"])
		district := qu.ObjToString(v["district"])
		town := qu.ObjToString(v["town"])
		if codenum == 2 {
			fnx = append(fnx, v)
		} else if codenum == 4 {
			citys_maps[province] = append(citys_maps[province], v)
		} else if codenum == 6 {
			if districts_maps[province] == nil {
				districts_maps[province] = make(map[string][]map[string]interface{}, 0)
			}
			districts_maps[province][city] = append(districts_maps[province][city], v)
		} else if codenum == 9 {
			if towns_maps[province] == nil {
				towns_maps[province] = make(map[string]map[string][]map[string]interface{}, 0)
			}
			if towns_maps[province][city] == nil {
				towns_maps[province][city] = make(map[string][]map[string]interface{}, 0)
			}
			towns_maps[province][city][district] = append(towns_maps[province][city][district], v)
		} else if codenum == 12 {
			if jwhs_maps[province] == nil {
				jwhs_maps[province] = make(map[string]map[string]map[string][]map[string]interface{}, 0)
			}
			if jwhs_maps[province][city] == nil {
				jwhs_maps[province][city] = make(map[string]map[string][]map[string]interface{}, 0)
			}
			if jwhs_maps[province][city][district] == nil {
				jwhs_maps[province][city][district] = make(map[string][]map[string]interface{}, 0)
			}
			jwhs_maps[province][city][district][town] = append(jwhs_maps[province][city][district][town], v)
		}
	}

	//初始化城市全称
	for _, provinces := range fnx {
		all_province := qu.ObjToString(provinces["all_province"]) //省全称
		jc_province := qu.ObjToString(provinces["province"])      //省简称
		//加载省信息
		e.Trie_Full_Province.AddWords(all_province) //加入省全称Trie(k:浙江省)
		p := &Province{}
		p.Name = all_province                     //省全称:浙江省
		p.Brief = jc_province                     //省简称:浙江
		e.Trie_Sim_Province.AddWords(jc_province) //加入省简称Trie(k:浙江)
		e.ProvinceMap[all_province] = jc_province //浙江省:浙江
		e.ProvinceBriefMap[jc_province] = p       //浙江:省信息{}
		if province_alias, ok := provinces["province_alias"].([]interface{}); ok {
			for _, vprovince_alias := range province_alias {
				e.ProvinceBriefMap[qu.ObjToString(vprovince_alias)] = p
			}
		}
		//加载市信息
		citys := citys_maps[jc_province]
		isok := make(map[string]bool)
		for _, vcity := range citys {
			qc_city := qu.ObjToString(vcity["city"])
			jc_city := qu.ObjToString(vcity["brief_city"])
			e.Trie_Full_City.AddWords(qc_city) //加入市全称Trie(k:杭州市)
			c := &City{}
			c.Name = qc_city //市全称:杭州市
			if jc_city != "" {
				c.Brief = jc_city                 //市简称:杭州
				e.Trie_Sim_City.AddWords(c.Brief) //加入市简称Trie(k:杭州)
				e.CityMap[qc_city] = c.Brief      //杭州市:杭州
				e.CityBriefMap[c.Brief] = c       //杭州:市信息{}
				e.CityFullMap[qc_city] = c        //杭州市:市信息{}
			}
			c.P = p
			if city_alias, ok := vcity["city_alias"].([]interface{}); ok {
				for _, vcity_alias := range city_alias {
					strvcity_alias := qu.ObjToString(vcity_alias)
					if isok[jc_province+"_"+strvcity_alias] {
						continue
					}
					e.CityBriefMap[strvcity_alias] = c
					e.initDistricts(jc_province, strvcity_alias, c, jc_city, districts_maps, towns_maps, jwhs_maps)
					isok[jc_province+"_"+strvcity_alias] = true
				}
			}
			if isok[jc_province+"_"+qc_city] {
				continue
			}
			e.initDistricts(jc_province, qc_city, c, jc_city, districts_maps, towns_maps, jwhs_maps)
		}
	}

	e.Trie_Fulls = []*Trie{e.Trie_Full_Province, e.Trie_Full_City, e.Trie_Full_District, e.Trie_Full_Street, e.Trie_Full_Community}
	e.Trie_Sims = []*Trie{e.Trie_Sim_Province, e.Trie_Sim_City, e.Trie_Sim_District}
}

//加载区县
func (e *ExtractTask) initDistricts(jc_province string, qc_city string, c *City,
	jc_city string, districts_maps map[string]map[string][]map[string]interface{},
	towns_maps map[string]map[string]map[string][]map[string]interface{},
	jwhs_maps map[string]map[string]map[string]map[string][]map[string]interface{}) {
	districts := districts_maps[jc_province][qc_city]
	for _, vdistricts := range districts {
		qc_district := qu.ObjToString(vdistricts["district"])
		jc_district := qu.ObjToString(vdistricts["brief_district"])
		d := &District{}
		d.Name = qc_district
		d.C = c
		e.Trie_Full_District.AddWords(qc_district) //加入区或县全称Trie
		if jc_district != "" {
			e.Trie_Sim_District.AddWords(jc_district) //加入区或县简称Trie
			//初始化城市简称
			c := e.CityBriefMap[jc_city]
			dfullarr := e.NewDistrictSimAndAll[jc_district]
			dfullcity := map[string]*City{qc_district: c}
			if len(dfullarr) == 0 {
				tmparr := []map[string]*City{dfullcity}
				e.NewDistrictSimAndAll[jc_district] = tmparr
			} else {
				e.NewDistrictSimAndAll[jc_district] = append(e.NewDistrictSimAndAll[jc_district], dfullcity)
			}
		}
		ctmp := e.NewDistrictCityMap[qc_district]
		if len(ctmp) == 0 {
			tmpcarr := []*City{c}
			e.NewDistrictCityMap[qc_district] = tmpcarr
		} else {
			e.NewDistrictCityMap[qc_district] = append(e.NewDistrictCityMap[qc_district], c)
		}
		if district_alias, ok := vdistricts["district_alias"].([]interface{}); ok {
			for _, vdistrict_alias := range district_alias {
				strvdistrict_alias := qu.ObjToString(vdistrict_alias)
				e.Trie_Full_District.AddWords(strvdistrict_alias) //加入区或县全称Trie
				ctmp := e.NewDistrictCityMap[strvdistrict_alias]
				if len(ctmp) == 0 {
					tmpcarr := []*City{c}
					e.NewDistrictCityMap[strvdistrict_alias] = tmpcarr
				} else {
					e.NewDistrictCityMap[strvdistrict_alias] = append(e.NewDistrictCityMap[strvdistrict_alias], c)
				}
			}
		}
		//街道
		towns := towns_maps[jc_province][qc_city][qc_district]
		for _, vtown := range towns {
			strvtown := qu.ObjToString(vtown["town"])
			s := &Street{}
			s.Name = strvtown
			s.D = d
			e.Trie_Full_Street.AddWords(strvtown) //加入街道全称Trie
			dtmp := e.NewStreetDistrictMap[strvtown]
			if len(dtmp) == 0 {
				tmpdarr := []*District{d}
				e.NewStreetDistrictMap[strvtown] = tmpdarr
			} else {
				e.NewStreetDistrictMap[strvtown] = append(e.NewStreetDistrictMap[strvtown], d)
			}
			//村、居委会
			//jwhs := jwhs_maps[jc_province][qc_city][qc_district][strvtown]
			//for _, vjwh := range jwhs {
			//	strvillage := qu.ObjToString(vjwh["village"])
			//	e.Trie_Full_Community.AddWords(strvillage) //加入居委会、村全称Trie
			//	cttmp := e.CommunityDistrictMap[strvillage]
			//	if len(cttmp) == 0 {
			//		tmpdarr := []*District{d}
			//		e.CommunityDistrictMap[strvillage] = tmpdarr
			//	} else {
			//		e.CommunityDistrictMap[strvillage] = append(e.CommunityDistrictMap[strvillage], d)
			//	}
			//}
		}

	}
}
func (t *Trie) AddWords(words ...string) {
	cur := t
	for _, v := range words {
		for _, one := range v {
			if cur.c == nil {
				cur.c = map[rune]*Trie{}
			}
			n := cur.c[one]
			if n == nil {
				n = &Trie{}
				cur.c[one] = n
			}
			cur = n
		}
		cur.y = true
		cur = t
	}
}

func (t *Trie) Get(word string) bool {
	cur := t
	for _, one := range word {
		n := cur.c[one]
		if n == nil {
			return false
		}
		cur = n
	}
	return cur.y
}


func (e *ExtractTask) InitVar() {
	defer qu.Catch()
	//初始化Trie
	//全称
	e.Trie_Full_Province = &Trie{}
	e.Trie_Full_City = &Trie{}
	e.Trie_Full_District = &Trie{}
	e.Trie_Full_Street = &Trie{}
	e.Trie_Full_Community = &Trie{}
	//简称
	e.Trie_Sim_Province = &Trie{}
	e.Trie_Sim_City = &Trie{}
	e.Trie_Sim_District = &Trie{}

	//初始化分词
	e.Seg_PCD = &gse.Segmenter{}
	e.Seg_SV = &gse.Segmenter{}
	e.Seg_PCD.LoadDict("./pcd.txt")
	e.Seg_SV.LoadDict("./sv.txt")

	if e.ProvinceMap == nil {
		e.ProvinceMap = make(map[string]string)
	}
	if e.CityMap == nil {
		e.CityMap = make(map[string]string)
	}
	if e.DistrictSimAndAll == nil {
		e.DistrictSimAndAll = make(map[string]string)
	}
	if e.NewDistrictSimAndAll == nil {
		e.NewDistrictSimAndAll = make(map[string][]map[string]*City)
	}

	if e.CityBriefMap == nil {
		e.CityBriefMap = make(map[string]*City)
	}
	if e.CityFullMap == nil {
		e.CityFullMap = make(map[string]*City)
	}
	if e.ProvinceBriefMap == nil {
		e.ProvinceBriefMap = make(map[string]*Province)
	}
	if e.NewDistrictCityMap == nil {
		e.NewDistrictCityMap = make(map[string][]*City)
	}

	if e.NewStreetDistrictMap == nil {
		e.NewStreetDistrictMap = make(map[string][]*District)
	}
	if e.CommunityDistrictMap == nil {
		e.CommunityDistrictMap = make(map[string][]*District)
	}

}





