using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using trieTree.xiaoshi.sz.com;

namespace testtrieTree
{
    public class AddressUtility
    {
        trieTree.xiaoshi.sz.com.trieTree tree = new trieTree.xiaoshi.sz.com.trieTree();
        private Hashtable keyAddress = new Hashtable();
        public AddressUtility() {

            string filePath = "data/tree.bin";

            if (File.Exists(filePath))
            {
                tree.Load(filePath);
            }
            else
            {
                string csvFile = "data/area_code_2024.csv";
                using (StreamReader sr = new StreamReader(csvFile))
                {
                    while (!sr.EndOfStream)
                    {
                        string line = sr.ReadLine();
                        string[] values = line.Split(',');

                        //if (!keyAddress.ContainsKey(values[0]))
                        //{
                        //    keyAddress.Add(values[0], values[1]);
                        //}

                        switch (values[2])
                        {
                            case "1":
                                tree.AddWord(values[1], values[0] + values[1]);

                                if (values[1].EndsWith("市") || values[1].EndsWith("省"))
                                    tree.AddWord(values[1].Substring(0, values[1].Length - 1), values[0] + values[1]);

                                if (values[1].EndsWith("自治区"))
                                    tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);

                                break;
                            case "2":
                                if (values[1] != "市辖区"
                                    && values[1] != "省直辖县级行政区划"
                                    && values[1] != "县"
                                    && values[1] != "自治区直辖县级行政区划")
                                {
                                    tree.AddWord(values[1], values[0] + values[1]);
                                    if (values[1].EndsWith("市") || values[1].EndsWith("盟"))
                                    {
                                        tree.AddWord(values[1].Substring(0, values[1].Length - 1), values[0] + values[1]);
                                    }

                                    if (values[1].EndsWith("地区"))
                                    {
                                        tree.AddWord(values[1].Substring(0, values[1].Length - 2), values[0] + values[1]);
                                    }
                                    #region 特殊市级名称
                                    //朝鲜族自治州 
                                    //阿坝藏族羌族自治州 
                                    //甘孜藏族自治州
                                    //凉山彝族自治州
                                    //黔西南布依族苗族自治州
                                    //黔东南苗族侗族自治州
                                    //黔南布依族苗族自治州
                                    //楚雄彝族自治州
                                    //红河哈尼族彝族自治州
                                    //文山壮族苗族自治州
                                    //西双版纳傣族自治州
                                    //大理白族自治州
                                    //德宏傣族景颇族自治州
                                    //怒江傈僳族自治州
                                    //临夏回族自治州
                                    //甘南藏族自治州
                                    //海北藏族自治州
                                    //黄南藏族自治州
                                    //海南藏族自治州
                                    //果洛藏族自治州
                                    //玉树藏族自治州
                                    //海西蒙古族藏族自治州
                                    //昌吉回族自治州
                                    //博尔塔拉蒙古自治州
                                    //巴音郭楞蒙古自治州
                                    //克孜勒苏柯尔克孜自治州
                                    //伊犁哈萨克自治州
                                    #endregion

                                }
                                break;

                            case "3":

                                tree.AddWord(values[1], values[0] + values[1]);
                                if (values[1].EndsWith("旗") || values[1].EndsWith("市") || (values[1].EndsWith("区") && !values[1].EndsWith("地区")) || (values[1].EndsWith("县") && !values[1].EndsWith("自治县")))
                                {
                                    if (values[1].Length > 2)
                                    {
                                        tree.AddWord(values[1].Substring(0, values[1].Length - 1), values[0] + values[1]);
                                    }

                                }

                                if (values[1].EndsWith("地区"))
                                {
                                    if (values[1].Length > 3)
                                        tree.AddWord(values[1].Substring(0, values[1].Length - 2), values[0] + values[1]);
                                }

                                if (values[1].EndsWith("自治县"))
                                {
                                    if (values[1].Length > 4)
                                        tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);
                                }
                                #region 特殊区县级名称
                                //和布克赛尔蒙古自治县
                                //察布查尔锡伯自治县
                                //塔什库尔干塔吉克自治县
                                //焉耆回族自治县
                                //木垒哈萨克自治县
                                #endregion

                                break;

                            case "4":
                                if (!values[1].Contains("直辖"))
                                {
                                    tree.AddWord(values[1], values[0] + values[1]);

                                }
                                break;

                            case "5":
                                //break;
                                tree.AddWord(values[1], values[0] + values[1]);

                                if (values[1].EndsWith("居委会") || values[1].EndsWith("生活区"))
                                {
                                    if (values[1].Length > 4)
                                    {
                                        tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);
                                    }
                                }

                                if (values[1].EndsWith("村委会"))
                                {
                                    //if (values[1].Length > 4)
                                    //{
                                    //    tree.AddWord(values[1].Substring(0, values[1].Length - 3), values[0] + values[1]);
                                    //}
                                    tree.AddWord(values[1].Substring(0, values[1].Length - 2), values[0] + values[1]);

                                }

                                if (values[1].EndsWith("居民委员会"))
                                {
                                    //if (values[1].Length > 6)
                                    //{
                                    //    tree.AddWord(values[1].Substring(0, values[1].Length - 5), values[0] + values[1]);
                                    //}
                                }

                                break;
                            default:
                                break;
                        }
                        //tree.AddWord(values[1],values[0]);
                    }
                }

                tree.AddWord("工业园区", "320576000000苏州工业园区");
                tree.AddWord("高新区", "320505000000虎丘区");
                tree.AddWord("科技城", "320505000000虎丘区");
                tree.AddWord("芙蓉村", "320412106003芙蓉社区居委会（含芙蓉村村委）");
                tree.AddWord("芙蓉社区", "320412106003芙蓉社区居委会（含芙蓉村村委）");
                tree.AddWord("襄樊", "420600000000襄阳市");
                tree.AddWord("襄樊市", "420600000000襄阳市");
                tree.AddWord("四方区", "370203000000市北区");

                Console.WriteLine(DateTime.Now);
                tree.Save(filePath);
            }

            

        }
        public List<string>? Paser(string address)
        {
            List<List<string>> list = new List<List<string>>();
            int i = 0;
            bool shenAdded = false;
            bool shiAdded = false;
            bool quxianAdded = false;
            
            while (i < address.Length)
            {
                int temIndex = 0;
                treeNode treeNode = tree.maxPrif(address.Substring(i), out temIndex);
                if (treeNode != null)
                {
                    //list.Add(treeNode.EndValues);
                    //Console.WriteLine($"{address.Substring(i,temIndex)},{i},{temIndex + i}");
                    foreach (string key in treeNode.EndValues)
                    {
                        string strId = key.Substring(0,12);
                        if (strId.EndsWith("0000000000"))
                        {
                            if (!shenAdded)
                            {
                                addkeyToResult(key, list);
                                shenAdded = true;
                            }
                            continue;
                        }

                        if (strId.EndsWith("00000000") )
                        {
                            if (!shiAdded)
                            {
                                addkeyToResult(key, list);
                                shiAdded = true;
                            }
                            continue;
                        }

                        //if (strId.EndsWith("000000"))
                        //{
                        //    if (!quxianAdded)
                        //    {
                        //        addkeyToResult(key, list);
                        //        quxianAdded = true;
                        //    }
                        //    continue;
                        //}

                        addkeyToResult(key, list);

                        //Console.WriteLine($"\t{key}");
                    }
                    i = i+ temIndex;
                }

                i++;
            }

            
            List<string>? retList = null;

            //int maxLength =0;
            //foreach (List<string> strings in list)
            //{
            //    if(strings.Count > maxLength && IncludeShenShi(strings))
            //    {
            //        maxLength = strings.Count; 

            //        retList = strings;
            //    }
            //}




            double maxResult =0;
            foreach (List<string> strings in list)
            {
                double temResult = CalResult(strings);
                if(temResult > maxResult)
                {
                    maxResult = temResult;
                    retList = strings;
                }
            }

            if (retList != null)
            {
                retList.Sort();
            }


            return tree.formatAddress(retList);
        }

        private double CalResult(List<string> list)
        {
            double result = 0;
            foreach (string str in list)
            {
                string value = str.Substring(0, 12);
                if (value.EndsWith("0000000000"))
                {
                    result += 1.2;
                }
                else
                {
                    if (value.EndsWith("00000000"))
                    {
                        result += 1.1;
                    }
                    else
                    {
                        if (value.EndsWith("000000"))
                        {
                            result += 0.9;
                        }
                        else
                        {
                            if (value.EndsWith("000"))
                            {
                                result += 0.6;
                            }
                            else
                            {
                                result += 0.4;
                            }
                        }
                    }
                }
            }
            return result;
        }

        private bool IncludeShenShi(List<string> strings)
        {
            foreach (string key in strings)
            {
                string value = key.Substring(0, 12);
                if(value.EndsWith("0000000000") || value.EndsWith("00000000"))
                {
                    return true;
                }
            }
            return false;
        }

        
        public bool Search(string str)
        {
            return tree.Search(str, out _);
        }

        private void addkeyToResult(string key, List<List<string>> list)
        {
            if(list != null)
            {
                if (list.Count > 0) { 
                    bool isAdded = false;
                    List<List<string>> strings1 = new List<List<string>>();
                    
                    foreach (List<string> item in list)
                    {
                        List<string> tempList = new List<string>();
                        foreach (string key2 in item)
                        {
                            if(isSub(key2, key))
                            {
                                if (!tempList.Contains(key2))
                                {
                                    tempList.Add(key2);
                                }
                            }
                        }

                        if (tempList.Count > 0)
                        {
                            if (tempList.Count == item.Count)
                            {
                                if (!item.Contains(key))
                                {
                                    item.Add(key);
                                }

                                isAdded = true;
                                break;

                            }
                            else
                            {
                                tempList.Add(key);
                                strings1.Add(tempList);
                                //isAdded = true;
                            }

                            
                        }
                        

                    }

                    if (!isAdded)
                    {
                        if (strings1.Count > 0)
                        {
                            List<string> strings2 = new List<string>();
                            int lstLength = 0;
                            foreach(List<string> lst in strings1)
                            {
                                if (lstLength < lst.Count)
                                {
                                    lstLength = lst.Count;
                                    strings2 = lst;
                                }
                            }

                            list.Add(strings2);
                        }
                        else
                        {
                            List<string> strings = new List<string>() { key };
                            list.Add(strings);
                        }
                            
                    }
                }
                else
                {
                    List<string> strings = new List<string>() { key};
                    list.Add(strings);
                }
            }
            else
            {
                throw new Exception("list不能未空！");
            }
        }

        private bool isSub(string key2, string key)
        {
            if (key2 != null && key != null)
            {
                string s1 = TrimRightZero(key2.Substring(0, 12));
                string s2 = TrimRightZero(key.Substring(0, 12));

                return (s1.StartsWith(s2) || s2.StartsWith(s1));
            }

            return false;
        }

        private string TrimRightZero(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return str;
            }
            else
            {
                string str1= str.Substring(0, 2);
                string str2 = str.Substring(2, 2);
                string str3 = str.Substring(4, 2);
                string str4 = str.Substring(6, 3); 
                string str5 = str.Substring(9, 3);

                if (str5 != "000")
                {
                    return str1 + str2 +str3 +str4 + str5;
                }
                else
                {
                    if(str4 != "000")
                    {
                        return str1+str2 +str3 +str4 ;
                    }
                    else
                    {
                        if(str3 != "00")
                        {
                            return str1 + str2 + str3 ;
                        }
                        else
                        {
                            if(str2 != "00")
                            {
                                return str1 + str2 ;
                            }
                            else
                            {
                                return str1 ;
                            }
                        }
                    }
                }
                //for (int i = str.Length - 1; i >= 0; i--)
                //{
                //    if (str[i] != '0')
                //    {
                //        return str.Substring(0, i+1);
                //    }
                //}

                //return "";
            }
        }
    }
}
