using BO.BO;
using BO.Utils;
using BO.Utils.BillRpc;
using BWP.WinFormControl;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace QualityAndOrder
{
  public partial class QualityOrderForm : Form, IAfterLogin
  {
    #region IAfterLogin
    public string RoleName
    {
      get { return "验质员"; }
    }

    public Form Generate()
    {
      return this;
    }

    #endregion

    private delegate void InvokeHandler();

    List<Tuple<string, string>> hogGradeList;
    List<HouseSplitEntity> houseList;
    List<SanctionSplit3Part> sanctionList;
    List<HouseAndSanctionList> weightBills;
    HouseAndSanctionEdit Dmo;
    Thread syncThread;
    readonly Color btnSelectForeColor = Color.FromArgb(255, 255, 255);
    readonly Color btnSelectBackColor = Color.FromArgb(66, 163, 218);
    Color btnUnSelectForeColor = SystemColors.ControlText;
    Color btnUnSelectBackColor = Color.FromArgb(225, 225, 225);

    public QualityOrderForm()
    {
      InitializeComponent();
      testTimeInput.Date = DateTime.Today;
      this.uTabControl1.Selected += (sender, e) =>
      {
        this.Text = e.TabPage.Text;
      };
      sanctionGrid.AutoGenerateColumns = false;
      weightBillGrid.AutoGenerateColumns = false;
      weightBillGrid.DataSource = null;
      hogGradeList = BaseInfoRpcUtil.GetBaseInfoEntity("GetHogGradeList");
      houseList = HouseSplitEntity.Init(BaseInfoRpcUtil.GetBaseInfoEntity("GetLiveColonyHouseList"));
      sanctionList = SanctionSplit3Part.Init(BaseInfoRpcUtil.GetSanctionList());
      AddKeyPadForTab1();
      AddHogGradeBtn();
      BindSanctionGrid();

      AddHouseBtn();

      numberBox.LostFocus += (sender, e) => { flag = 1; };
      sanctionGrid.GotFocus += (sender, e) => { flag = 2; };
      this.FormClosing += delegate
      {
        if (syncThread != null && syncThread.IsAlive)
          syncThread.Abort();
        if (orderSyncTask != null && orderSyncTask.IsAlive)
          orderSyncTask.Abort();
        if (bt2SyncTask != null && bt2SyncTask.IsAlive)
          bt2SyncTask.Abort();
        if (bt3SyncTask != null && bt3SyncTask.IsAlive)
          bt3SyncTask.Abort();
      };

      Tab2Init();
      Tab3Init();
    }

    HouseAndSanctionList lastFirstSelect;
    private void SyncTask()
    {
      while (true)
      {
        this.Invoke(new InvokeHandler(delegate()
        {
          weightBills = HouseAndSanctionRpc.GetHouseAndSanctionList(testTimeInput.Date.Value);
          BindWeightBillGrid();
          BindNumberLabel();
        }));
        Thread.Sleep(5000);
      }
    }

    int flag = 1;

    List<Button> hogGradeBtn = new List<Button>();
    List<Button> houseBtn = new List<Button>();

    private void BindWeightBillGrid()
    {
      weightBillGrid.DataSource = weightBills.OrderBy(x => x.ID).OrderBy(x => x.AlreadyHouse).ToList();
      if (lastFirstSelect == null && weightBillGrid.CurrentRow != null)
      {
        lastFirstSelect = weightBillGrid.CurrentRow.DataBoundItem as HouseAndSanctionList;
        if (lastFirstSelect.AlreadyHouse)
        {
          lastFirstSelect = null;
          weightBillGrid.CurrentRow.DefaultCellStyle.BackColor = Color.YellowGreen;
        }
      }
      foreach (DataGridViewRow row in weightBillGrid.Rows)
      {
        if ((bool)row.Cells["W_AlreadyHouse"].Value)
          row.DefaultCellStyle.BackColor = Color.YellowGreen;
        if (lastFirstSelect != null && lastFirstSelect.ID == (long)row.Cells["W_ID"].Value)
        {
          lastFirstSelect = row.DataBoundItem as HouseAndSanctionList;
          if (lastFirstSelect.AlreadyHouse)
            row.DefaultCellStyle.BackColor = Color.Yellow;
          else
            row.DefaultCellStyle.BackColor = weightBillGrid.RowsDefaultCellStyle.SelectionBackColor;
        }
      }
      InitScrollBar();
      weightBillGrid.ClearSelection();
      try
      {
        if (firstRoll != -1)
          weightBillGrid.FirstDisplayedScrollingRowIndex = firstRoll;
      }
      catch
      {
        firstRoll = -1;
      }
      weightBillGrid.Refresh();
    }

    private void AddKeyPadForTab1()
    {
      for (var i = 1; i < 10; i++)
      {
        var btn = new Button() { Name = "_" + i, Text = i.ToString(), Size = new Size(80, 60), TextAlign = ContentAlignment.MiddleCenter, Margin = new Padding { All = 10 }, Font = new Font("宋体", 15) };
        btn.Click += (sender, e) =>
        {
          if (flag == 1)
          {
            numberBox.Text += btn.Text;
          }
          else if (flag == 2)
            InputSanctionNumber(btn.Text);
        };
        keyBoardPanel.Controls.Add(btn);
      }
      var zero = new Button() { Name = "_0", Text = "0", Size = new Size(80, 60), TextAlign = ContentAlignment.MiddleCenter, Margin = new Padding { All = 10 }, Font = new Font("宋体", 15) };
      zero.Click += (sender, e) =>
      {
        if (flag == 1)
        {
          if (!string.IsNullOrEmpty(numberBox.Text))
            numberBox.Text += "0";
        }
        else if (flag == 2)
          InputSanctionNumber("0");
      };
      keyBoardPanel.Controls.Add(zero);
      var back = new Button() { Name = "_back", Text = "←", Size = new Size(80, 60), TextAlign = ContentAlignment.MiddleCenter, Margin = new Padding { All = 10 }, Font = new Font("宋体", 15) };
      back.Click += (sender, e) =>
      {
        if (flag == 1)
        {
          if (!string.IsNullOrEmpty(numberBox.Text))
            numberBox.Text = numberBox.Text.Substring(0, numberBox.Text.Length - 1);
        }
        else if (flag == 2)
          InputSanctionNumber("←");
      };
      keyBoardPanel.Controls.Add(back);

      var clear = new Button() { Name = "_clear", Text = "清空", Size = new Size(80, 60), TextAlign = ContentAlignment.MiddleCenter, Margin = new Padding { All = 10 }, Font = new Font("宋体", 15) };
      clear.Click += (sender, e) =>
      {
        if (flag == 1)
        {
          numberBox.Text = string.Empty;
        }
        else if (flag == 2)
          InputSanctionNumber("清空");
      };
      keyBoardPanel.Controls.Add(clear);
    }

    void InputSanctionNumber(string input)
    {
      if (sanctionGrid.CurrentCell == null)
        throw new Exception("请选择一项异常");
      var tag = sanctionGrid.CurrentRow.DataBoundItem as SanctionSplit3Part;
      var idx = sanctionGrid.SelectedCells[0].ColumnIndex;
      if (idx > 3)
      {
        if (tag.Sanction_ID3 == 0)
          return;
        tag.Number3 = GetAfterNumber(tag.Number3, input);
      }
      else if (idx > 1)
      {
        if (tag.Sanction_ID2 == 0)
          return;
        tag.Number2 = GetAfterNumber(tag.Number2, input);
      }
      else
      {
        if (tag.Sanction_ID1 == 0)
          return;
        tag.Number1 = GetAfterNumber(tag.Number1, input);
      }
      sanctionGrid.Refresh();
    }

    int? GetAfterNumber(int? oldValue, string input)
    {
      switch (input)
      {
        case "0":
          if (oldValue.HasValue)
            return int.Parse(oldValue + "0");
          return null;
        case "←":
          if (oldValue.HasValue)
          {
            var s = oldValue.ToString();
            s = s.Substring(0, s.Length - 1);
            if (string.IsNullOrEmpty(s))
              return null;
            return int.Parse(s);
          }
          return null;
        case "清空":
          return null;
        default:
          var sn = "";
          if (oldValue.HasValue)
            sn = oldValue.ToString();
          sn += input;
          return int.Parse(sn);
      }
    }

    Button currentBtn;
    private void AddHogGradeBtn()
    {
      foreach (var item in hogGradeList)
      {
        var btn = new Button() { Name = "_" + item.Item1, Tag = item, Text = item.Item2, Size = new Size(80, 60), TextAlign = ContentAlignment.MiddleCenter, Margin = new Padding { Left = 20, Top = 5 }, Font = new Font("宋体", 15), BackColor = btnUnSelectBackColor };
        btn.Click += (sender, e) =>
        {
          if (currentBtn != null)
            SetBtnUnCheck(currentBtn);
          if (currentBtn != btn)
          {
            currentBtn = btn;
            SetBtnChecked(currentBtn);
          }
          else
            currentBtn = null;
        };
        hogGradeBtn.Add(btn);
        hogGradePanel.Controls.Add(btn);
      }
    }

    private void BindSanctionGrid()
    {
      sanctionGrid.DataSource = sanctionList;
      sanctionGrid.Refresh();
    }

    List<Button> houseSelectedBtn = new List<Button>();

    private void AddHouseBtn()
    {
      int pageSize = 48;
      foreach (var houseItems in houseList)
      {
        var tabPage = new TabPage(houseItems.Part);
        tabPage.Name = string.Format("house_{0}", houseItems.Part);
        var flowCount = houseItems.Details.Count / 48;
        if (houseItems.Details.Count % 48 != 0)
          flowCount += 1;
        FlowLayoutPanel pageBtnPanel = null;
        for (var i = 0; i < flowCount; i++)
        {
          var houseFlow = new FlowLayoutPanel() { RightToLeft = RightToLeft.No, Name = string.Format("houseFlow_{0}", houseItems.Part), BorderStyle = BorderStyle.FixedSingle };
          if (flowCount > 1)
          {
            if (i == 0)
            {
              pageBtnPanel = new FlowLayoutPanel() { Dock = DockStyle.Bottom, Height = 65, RightToLeft = RightToLeft.No, BorderStyle = BorderStyle.FixedSingle };
              pageBtnPanel.Location = new Point(3, 492 - 65);
            }
            else
              houseFlow.Visible = false;
            var btn = new Button() { Text = (i + 1).ToString(), Tag = houseFlow, Size = new Size(75, 55), TextAlign = ContentAlignment.MiddleCenter, Margin = new Padding { All = 5 }, Font = new Font("宋体", 15) };
            pageBtnPanel.Controls.Add(btn);
            btn.Click += (sender, e) =>
            {
              var currentBind = btn.Tag as FlowLayoutPanel;
              foreach (var subControl in pageBtnPanel.Controls)
              {
                var pb = subControl as Button;
                var p = pb.Tag as FlowLayoutPanel;
                p.Visible = currentBind == p;
              }
            };
            houseFlow.Width = 709;
            houseFlow.Height = 492 - 70;
          }
          else
            houseFlow.Dock = DockStyle.Fill;
          tabPage.Controls.Add(houseFlow);
          if (pageBtnPanel != null)
            tabPage.Controls.Add(pageBtnPanel);
          int idx = i * pageSize;
          for (var j = 0; j < pageSize; j++)
          {
            var padding = new Padding { All = 5 };
            if ((idx + 1) % 8 != 0 && (idx + 1) % 4 == 0)
              padding = new Padding(5, 5, 15, 5);
            var house = houseItems.Details[idx];
            var btn = new Button() { Name = "_" + house.Item1, Tag = house, Text = house.Item2, Size = new Size(77, 60), TextAlign = ContentAlignment.MiddleCenter, Margin = padding, Font = new Font("宋体", 12), BackColor = btnUnSelectBackColor };
            btn.Click += (sender, e) =>
            {
              if (houseSelectedBtn.Contains(btn))
              {
                btn.BackColor = btnUnSelectBackColor;
                btn.ForeColor = btnUnSelectForeColor;
                houseSelectedBtn.Remove(btn);
              }
              else
              {
                btn.BackColor = btnSelectBackColor;
                btn.ForeColor = btnSelectForeColor;
                houseSelectedBtn.Add(btn);
              }
            };
            houseBtn.Add(btn);
            houseFlow.Controls.Add(btn);
            idx += 1;
            if (idx == houseItems.Details.Count)
              break;
          }
        }
        housePanel.TabPages.Add(tabPage);
      }
      if (housePanel.TabPages.Count != 0)
        housePanel.SelectedIndex = housePanel.TabPages.Count - 1;
    }

    private void closeBtn_Click(object sender, EventArgs e)
    {
      this.Close();
    }

    private void commitBtn_Click(object sender, EventArgs e)
    {
      GetDataFromUI();
      HouseAndSanctionRpc.UpdateInsertHouseAndSanction(Dmo);
      Dmo = null;
      weightBills = HouseAndSanctionRpc.GetHouseAndSanctionList(testTimeInput.Date.Value);
      BindWeightBillGrid();
      BindNumberLabel();
      ResetTab1Controls();
      UMessageBox.Show("提交成功！");
    }

    private void syncBtn_Click(object sender, EventArgs e)
    {
      if (syncThread == null || !syncThread.IsAlive)
      {
        syncThread = new Thread(SyncTask);
        syncThread.Start();
        syncBtn.BackColor = Color.FromArgb(15, 215, 107);
        syncBtn.ForeColor = Color.White;
      }
      else
      {
        syncThread.Abort();
        syncBtn.BackColor = Color.FromKnownColor(KnownColor.Control);
        syncBtn.ForeColor = Color.FromKnownColor(KnownColor.ControlText);
      }

      //BindNumberLabel();
      //tab1SyncThread = new Thread(StartQuery) { IsBackground = true };
      //tab1SyncThread.Start();
    }
    //bool isWork = false;
    //private void StartQuery()
    //{
    //  if (isWork)
    //    return;
    //  isWork = true;
    //  while (mainIsRun)
    //  {
    //    this.Invoke(new InvokeHandler(delegate()
    //    {
    //      weightBills = WeightBillRpc.GetUnHousedBill(testTimeInput.Date.Value);
    //      BindWeightBillGrid();
    //    }));
    //    Thread.Sleep(10000);
    //  }
    //}

    void BindNumberLabel()
    {
      var inHouseNumber = HouseAndSanctionRpc.GetDetailTotalNumber(testTimeInput.Date.Value);
      inHouseNumberLabel.Text = string.Format("{0}", inHouseNumber);
    }

    void GetDataFromUI()
    {
      if (Dmo == null)
      {
        if (lastFirstSelect == null)
          throw new Exception("请选择需要处理的记录");
        Dmo = new HouseAndSanctionEdit();
        Dmo.ID = lastFirstSelect.ID;
      }
      else
      {
        Dmo.HouseDetails.Clear();
        Dmo.SanctionDetails.Clear();
      }
      if (string.IsNullOrEmpty(numberBox.Text))
        throw new Exception("数量不能为空");
      if (currentBtn == null)
        throw new Exception("请选等级");
      if (houseSelectedBtn.Count == 0)
        throw new Exception("请选择圈舍");
      foreach (var btn in houseSelectedBtn)
      {
        var house = btn.Tag as Tuple<string, string>;
        var houseDetail = new WeightBill_HouseDetail() { WeightBill_ID = Dmo.ID, LiveColonyHouse_ID = long.Parse(house.Item1), LiveColonyHouse_Name = house.Item2 };
        Dmo.HouseDetails.Add(houseDetail);
        houseDetail.Index = Dmo.HouseDetails.Max(x => x.Index) + 1;
      }
      var gradeTag = currentBtn.Tag as Tuple<string, string>;
      Dmo.HogGrade_ID = long.Parse(gradeTag.Item1);
      Dmo.HogGrade_Name = gradeTag.Item2;
      Dmo.Number = int.Parse(numberBox.Text);
      foreach (DataGridViewRow row in sanctionGrid.Rows)
      {
        var tag = row.DataBoundItem as SanctionSplit3Part;
        if( (tag.Number1??0)!=0)
        {
          var detail = new WeightBill_SanctionDetail();
          Dmo.SanctionDetails.Add(detail);
          detail.WeightBill_ID = Dmo.ID;
          detail.Index = Dmo.SanctionDetails.Max(x => x.Index) + 1;
          detail.Sanction_ID = tag.Sanction_ID1;
          detail.AbnormalItem_ID = tag.AbnormalItem_ID1;
          detail.AbnormalItem_Name = tag.AbnormalItem_Name1;
          detail.Number = tag.Number1;
        }
        if ((tag.Number2 ?? 0) != 0)
        {
          var detail = new WeightBill_SanctionDetail();
          Dmo.SanctionDetails.Add(detail);
          detail.WeightBill_ID = Dmo.ID;
          detail.Index = Dmo.SanctionDetails.Max(x => x.Index) + 1;
          detail.Sanction_ID = tag.Sanction_ID2;
          detail.AbnormalItem_ID = tag.AbnormalItem_ID2;
          detail.AbnormalItem_Name = tag.AbnormalItem_Name2;
          detail.Number = tag.Number2;
        }
        if ((tag.Number3 ?? 0) != 0)
        {
          var detail = new WeightBill_SanctionDetail();
          Dmo.SanctionDetails.Add(detail);
          detail.WeightBill_ID = Dmo.ID;
          detail.Index = Dmo.SanctionDetails.Max(x => x.Index) + 1;
          detail.Sanction_ID = tag.Sanction_ID3;
          detail.AbnormalItem_ID = tag.AbnormalItem_ID3;
          detail.AbnormalItem_Name = tag.AbnormalItem_Name3;
          detail.Number = tag.Number3;
        }
      }
    }

    void ResetTab1Controls()
    {
      foreach (var item in houseSelectedBtn)
        SetBtnUnCheck(item);
      houseSelectedBtn.Clear();
      if (currentBtn != null)
        SetBtnUnCheck(currentBtn);
      numberBox.Text = string.Empty;

      foreach (var item in sanctionList)
        item.Number1 = item.Number2 = item.Number3 = null;
      sanctionGrid.Refresh();
      uTabControl2.SelectedIndex = 0;
      flag = 1;
    }

    private void weightBillGrid_CellClick(object sender, DataGridViewCellEventArgs e)
    {
      if (e.RowIndex < 0)
        return;

      if (lastFirstSelect != null)
      {
        foreach (DataGridViewRow row in weightBillGrid.Rows)
        {
          if (lastFirstSelect.ID == (long)row.Cells["W_ID"].Value)
          {
            row.DefaultCellStyle.BackColor = lastFirstSelect.AlreadyHouse ? Color.YellowGreen : weightBillGrid.RowsDefaultCellStyle.BackColor;
            break;
          }
        }
      }
      lastFirstSelect = weightBillGrid.CurrentRow.DataBoundItem as HouseAndSanctionList;
      weightBillGrid.CurrentRow.DefaultCellStyle.SelectionBackColor = lastFirstSelect.AlreadyHouse ? Color.Yellow : weightBillGrid.RowsDefaultCellStyle.SelectionBackColor;
      weightBillGrid.Refresh();

      ResetTab1Controls();
      Tab1AppToUI();
    }

    void Tab1AppToUI()
    {
      Dmo = HouseAndSanctionRpc.GetHouseAndSanctionDetail(lastFirstSelect.ID);
      numberBox.Text = string.Empty;
      if (Dmo.HogGrade_ID.HasValue)
      {
        var first = hogGradeBtn.FirstOrDefault(x => x.Name == "_" + Dmo.HogGrade_ID);
        if (first != null)
        {
          currentBtn = first;
          SetBtnChecked(currentBtn);
        }
      }
      foreach (var item in Dmo.HouseDetails)
      {
        var first = houseBtn.FirstOrDefault(x => x.Name == "_" + item.LiveColonyHouse_ID);
        if (first != null)
        {
          SetBtnChecked(first);
          houseSelectedBtn.Add(first);
        }
      }
      foreach (var item in Dmo.SanctionDetails)
      {
        var first = sanctionList.FirstOrDefault(x => x.AbnormalItem_ID1 == item.AbnormalItem_ID);
        if (first != null)
        {
          first.Number1 = item.Number;
          continue;
        }
        var second = sanctionList.FirstOrDefault(x => x.AbnormalItem_ID2 == item.AbnormalItem_ID);
        if (second != null)
        {
          second.Number2 = item.Number;
          continue;
        }
        var third = sanctionList.FirstOrDefault(x => x.AbnormalItem_ID3 == item.AbnormalItem_ID);
        if (third != null)
        {
          third.Number3 = item.Number;
          continue;
        }
      }
      sanctionGrid.DataSource = sanctionList;
      sanctionGrid.Refresh();
    }

    void SetBtnChecked(Button btn)
    {
      btn.BackColor = btnSelectBackColor;
      btn.ForeColor = btnSelectForeColor;
    }

    void SetBtnUnCheck(Button btn)
    {
      btn.BackColor = btnUnSelectBackColor;
      btn.ForeColor = btnUnSelectForeColor;
    }

    int firstRoll = -1;
    private void InitScrollBar()
    {
      vScrollBar1.Maximum = (weightBillGrid.RowCount - weightBillGrid.DisplayedRowCount(false) + 30) * weightBillGrid.RowTemplate.Height;
      vScrollBar1.Minimum = 0;
      vScrollBar1.SmallChange = weightBillGrid.RowTemplate.Height;
      vScrollBar1.LargeChange = weightBillGrid.RowTemplate.Height * 30;
      this.vScrollBar1.Scroll += (sender, e) =>
      {
        firstRoll = e.NewValue / weightBillGrid.RowTemplate.Height;
        weightBillGrid.FirstDisplayedScrollingRowIndex = firstRoll;
      };
    }
  }
  class SanctionSplit3Part
  {
    public long Sanction_ID1 { get; set; }

    public long AbnormalItem_ID1 { get; set; }

    public string AbnormalItem_Name1 { get; set; }

    public int? Number1 { get; set; }

    public long Sanction_ID2 { get; set; }

    public long AbnormalItem_ID2 { get; set; }

    public string AbnormalItem_Name2 { get; set; }

    public int? Number2 { get; set; }

    public long Sanction_ID3 { get; set; }

    public long AbnormalItem_ID3 { get; set; }

    public string AbnormalItem_Name3 { get; set; }

    public int? Number3 { get; set; }

    public static List<SanctionSplit3Part> Init(List<Tuple<long, long, string>> list)
    {
      var result = new List<SanctionSplit3Part>();
      var count = list.Count / 3;
      if (list.Count % 3 != 0)
        count += 1;
      for (var i = 0; i < count; i++)
      {
        var detail = new SanctionSplit3Part();
        result.Add(detail);
        var idx = i * 3;
        var item = list[idx];
        detail.Sanction_ID1 = item.Item1;
        detail.AbnormalItem_ID1 = item.Item2;
        detail.AbnormalItem_Name1 = item.Item3;
        idx += 1;
        if (idx == list.Count)
          break;
        item = list[idx];
        detail.Sanction_ID2 = item.Item1;
        detail.AbnormalItem_ID2 = item.Item2;
        detail.AbnormalItem_Name2 = item.Item3;
        idx += 1;
        if (idx == list.Count)
          break;
        item = list[idx];
        detail.Sanction_ID3 = item.Item1;
        detail.AbnormalItem_ID3 = item.Item2;
        detail.AbnormalItem_Name3 = item.Item3;
      }
      return result;
    }

    public static List<Tuple<long, long, string, int>> ReInit(List<SanctionSplit3Part> list)
    {
      var result = new List<Tuple<long, long, string, int>>();
      foreach (var item in list)
      {
        if ((item.Number1 ?? 0) != 0)
        {
          var detail = new Tuple<long, long, string, int>(item.Sanction_ID1, item.AbnormalItem_ID1, item.AbnormalItem_Name1, item.Number1.Value);
          result.Add(detail);
        }

        if (item.Sanction_ID2 == 0)
          break;
        if ((item.Number2 ?? 0) != 0)
        {
          var detail = new Tuple<long, long, string, int>(item.Sanction_ID2, item.AbnormalItem_ID2, item.AbnormalItem_Name2, item.Number2.Value);
          result.Add(detail);
        }
        if (item.Sanction_ID3 == 0)
          break;
        if ((item.Number3 ?? 0) != 0)
        {
          var detail = new Tuple<long, long, string, int>(item.Sanction_ID3, item.AbnormalItem_ID3, item.AbnormalItem_Name3, item.Number3.Value);
          result.Add(detail);
        }
      }

      return result;
    }
  }

  class HouseSplitEntity
  {
    public string Part { get; set; }

    List<Tuple<string, string>> details = new List<Tuple<string, string>>();
    public List<Tuple<string, string>> Details { get { return details; } }

    public static List<HouseSplitEntity> Init(List<Tuple<string, string>> list)
    {
      var result = new List<HouseSplitEntity>();
      foreach (var item in list)
      {
        var part = item.Item2[0].ToString();
        var first = result.FirstOrDefault(x => x.Part == part);
        if (first == null)
        {
          first = new HouseSplitEntity { Part = part };
          result.Add(first);
        }
        first.Details.Add(new Tuple<string, string>(item.Item1, item.Item2));
      }
      result.Reverse();
      return result;
    }
  }
}
