using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AyaNovaQBI
{
    public partial class Map : Form
    {
        private AyaType _Type = AyaType.Customer;
        private DataTable _aya;
        private DataTable _qb;

        //private VendorTypes _currentVendorType = 0;
        private viewtypes _currentView = viewtypes.All;
        //private RateTypes _currentRateType = 0;
        //private long _MostLikelyRateUnitChargeDescriptionID = 0;

        private enum viewtypes
        {
            All,
            Unlinked,
            Linked
        }

        public Map()
        {
            InitializeComponent();
            this.Icon = AyaNovaQBI.Properties.Resources.logo;

            _aya = new DataTable("AyaNova");
            _aya.Columns.Add("name", typeof(string));
            _aya.Columns.Add("id", typeof(long));
            _aya.Columns.Add("linked", typeof(string));

            //Case 339
            _aya.DefaultView.Sort = "name asc";
            gridAya.DataSource = _aya;

            _qb = new DataTable("QuickBooks");
            _qb.Columns.Add("name", typeof(string));
            _qb.Columns.Add("id", typeof(string));
            _qb.Columns.Add("linked", typeof(bool));

            //Case 339
            _qb.DefaultView.Sort = "name asc";
            gridQB.DataSource = _qb;
        }

        private void Map_Load(object sender, EventArgs e)
        {
            Initialize();
            gridAya.ClearSelection();
            gridQB.ClearSelection();
        }




        private void importSelectedItemsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private async void linkSelectedItemsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool IsAyaGrid = false;
            if (gridAya.SelectedRows.Count == 0 && gridQB.SelectedRows.Count == 0) return;

            IsAyaGrid = gridAya.SelectedRows.Count > 0;
            bool SaveIntegration = false;

            if (IsAyaGrid)
            {
                //we have selection now get qb item
                MapSelectQBItem s = new MapSelectQBItem();

                s.QBItems = _qb;

                if (s.ShowDialog() == DialogResult.Cancel)
                    return;

                var QBItemName = s.SelectedQBItemName;
                var QBItemId = s.SelectedQBItemId;
                s.Dispose();
                var selectedAyaNovaIds = new List<long>();
                StringBuilder selectedAyaNovaNames = new StringBuilder();

                foreach (DataGridViewRow r in gridAya.SelectedRows)
                {
                    selectedAyaNovaNames.AppendLine(r.Cells[0].Value.ToString());
                    selectedAyaNovaIds.Add((long)r.Cells[1].Value);
                }


                //#################################
                //LINKING

                LinkAyaObjectToQBConfirm d = new LinkAyaObjectToQBConfirm();
                d.QBItem = QBItemName;
                d.AyaItems = selectedAyaNovaNames.ToString();
                if (d.ShowDialog() != DialogResult.OK)
                    return;


                ////ok, link away...
                foreach (DataGridViewRow r in gridAya.SelectedRows)
                {
                    string AyaName = r.Cells[0].Value.ToString();
                    long AyaId = (long)r.Cells[1].Value;



                    //Is AyaNova object already mapped?
                    IntegrationItem m = util.QBIntegration.Items.FirstOrDefault(z => z.ObjectId == AyaId && z.AType == _Type);
                    if (m != null)
                    {
                        //Is it already linked to the selected qb object?

                        //Yes so do nothing and continue on to the next object
                        if (m.IntegrationItemId == QBItemId)
                            continue;
                        else
                        {

                            //No, AyaNova object was mapped elsewhere, prompt user if this is ok
                            if (MessageBox.Show(
                                $"AyaNova object: {AyaName}\r\nIs already linked to QuickBooks object: {m.IntegrationItemName}\r\nDo you really want to change the link to the QuickBooks object: {QBItemName}\r\n",
                                "Change link?", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                                == DialogResult.No) continue;

                        }

                        //If we're here it's because the object is already mapped
                        //but the users has signified they want to change the map to another object so...
                        if (!string.IsNullOrEmpty(QBItemId))//confirm not a removal
                        {
                            m.IntegrationItemId = QBItemId;
                            m.IntegrationItemName = QBItemName;
                            m.LastSync = System.DateTime.Now;
                            SaveIntegration = true;
                        }
                        else
                        {
                            //user is removing mapping so remove the integrationitem entirely from the collection
                            var didremove = util.QBIntegration.Items.Remove(m);
                            SaveIntegration = true;
                        }

                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(QBItemId))//confirm not a removal
                        {
                            //not already present, so add it, easy peasy...
                            m = new IntegrationItem { AType = _Type, IntegrationItemName = QBItemName, IntegrationItemId = QBItemId, LastSync = System.DateTime.Now, ObjectId = AyaId };
                            util.QBIntegration.Items.Add(m);
                            SaveIntegration = true;
                        }
                    }
                }

                if (SaveIntegration)
                {
                    await util.SaveIntegrationObject();
                    Initialize();
                }

                //#################################
            }
            else
            {

            }
        }


        #region Initialize stuff
        /// <summary>
        /// Determine if row should be added to grid or now
        /// based on current view preferences and if item is already 
        /// linked or not
        /// </summary>
        /// <param name="bLinked"></param>
        /// <returns></returns>
        private bool DisplayRow(bool bLinked)
        {
            switch (_currentView)
            {
                case viewtypes.All:
                    return true;

                case viewtypes.Linked:
                    return bLinked;

                case viewtypes.Unlinked:
                    return !bLinked;


            }
            return true;
        }


        private void Initialize()
        {

            //clear both lists
            _aya.Rows.Clear();
            _qb.Rows.Clear();



            //Case 147
            updateAyaNovaPricesToolStripMenuItem.Visible = false;

            switch (_Type)
            {

                case AyaType.Customer:
                    #region client


                    foreach (var i in util.AyaClientList)
                    {
                        if (i.Active)
                        {
                            var v = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.ObjectId == i.Id);
                            if (DisplayRow(v != null))
                                _aya.Rows.Add(new object[] { i.Name, i.Id, v == null ? null : v.IntegrationItemName });
                        }
                    }

                    //Fill QB table
                    foreach (DataRow dr in util.QBClients.Rows)
                    {
                        bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString());
                        if (DisplayRow(bLinked))
                            _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked });
                    }
                    #endregion client
                    break;
                case AyaType.Vendor:
                    #region Vendor


                    foreach (var i in util.AyaVendorList)
                    {
                        if (i.Active)
                        {
                            var v = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.ObjectId == i.Id);
                            if (DisplayRow(v != null))
                                _aya.Rows.Add(new object[] { i.Name, i.Id, v == null ? null : v.IntegrationItemName });
                        }
                    }

                    //Fill QB table 
                    foreach (DataRow dr in util.QBVendors.Rows)
                    {
                        bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString());
                        if (DisplayRow(bLinked))
                            _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked });
                    }
                    #endregion Vendor
                    break;
                case AyaType.ServiceRate:
                    #region Service rates
                    //_MostLikelyRateUnitChargeDescriptionID = 0;


                    foreach (var i in util.AyaServiceRateList)
                    {
                        if (i.Active)
                        {
                            var v = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.ObjectId == i.Id);
                            if (DisplayRow(v != null))
                                _aya.Rows.Add(new object[] { i.Name, i.Id, v == null ? null : v.IntegrationItemName });

                        }
                    }

                    //Fill QB table with QB items from prefetched table
                    foreach (DataRow dr in util.QBItems.Rows)
                    {
                        if ((util.qbitemtype)dr["Type"] == util.qbitemtype.Service || (util.qbitemtype)dr["Type"] == util.qbitemtype.OtherCharge)
                        {
                            bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString());
                            if (DisplayRow(bLinked))
                                _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked });
                        }
                    }
                    #endregion Rate
                    break;

                case AyaType.TravelRate:
                    #region TravelRate rates
                    //_MostLikelyRateUnitChargeDescriptionID = 0;


                    foreach (var i in util.AyaTravelRateList)
                    {
                        if (i.Active)
                        {
                            var v = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.ObjectId == i.Id);
                            if (DisplayRow(v != null))
                                _aya.Rows.Add(new object[] { i.Name, i.Id, v == null ? null : v.IntegrationItemName });
                        }
                    }

                    //Fill QB table with QB items from prefetched table
                    foreach (DataRow dr in util.QBItems.Rows)
                    {
                        if ((util.qbitemtype)dr["Type"] == util.qbitemtype.Service || (util.qbitemtype)dr["Type"] == util.qbitemtype.OtherCharge)
                        {
                            bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString());
                            if (DisplayRow(bLinked))
                                _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked });
                        }
                    }
                    #endregion Rate
                    break;

                case AyaType.Part:
                    #region Service parts
                    //case 632
                    //gridQB.DisplayLayout.Rows.TemplateAddRow.Hidden=true;

                    //Case 147
                    updateAyaNovaPricesToolStripMenuItem.Visible = true;

                    foreach (var i in util.AyaPartList)
                    {
                        if (i.Active)
                        {
                            var v = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.ObjectId == i.Id);
                            if (DisplayRow(v != null))
                                _aya.Rows.Add(new object[] { i.Name, i.Id, v == null ? null : v.IntegrationItemName });
                        }
                    }

                    //Fill QB table with QB items from prefetched table
                    foreach (DataRow dr in util.QBItems.Rows)
                    {
                        if ((util.qbitemtype)dr["Type"] == util.qbitemtype.Inventory || (util.qbitemtype)dr["Type"] == util.qbitemtype.NonInventory || (util.qbitemtype)dr["Type"] == util.qbitemtype.Assembly)
                        {
                            bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString());
                            if (DisplayRow(bLinked))
                                _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked });
                        }
                    }
                    #endregion Part
                    break;

            }


        }


        #endregion init

        #region menu utility stuff

        private void showSubItemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Set the current clicked item to item
            ToolStripMenuItem item = sender as ToolStripMenuItem;
            // Loop through all items in the subMenu and uncheck them but do check the clicked item
            foreach (ToolStripMenuItem tempItemp in showToolStripMenuItem.DropDownItems)
            {
                if (tempItemp == item)
                    tempItemp.Checked = true;
                else
                    tempItemp.Checked = false;
            }
        }





        private void customersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            handleCheckOfObjectTypeMenuItem(sender, e);
            if (_Type == AyaType.Customer) return;
            _Type = AyaType.Customer;
            this.Text = "Map / Import - Customers";
            Initialize();
        }

        private void serviceRatesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            handleCheckOfObjectTypeMenuItem(sender, e);
            if (_Type == AyaType.ServiceRate) return;
            _Type = AyaType.ServiceRate;
            this.Text = "Map / Import - Service rates";
            Initialize();
        }

        private void travelRatesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            handleCheckOfObjectTypeMenuItem(sender, e);
            if (_Type == AyaType.TravelRate) return;
            _Type = AyaType.TravelRate;
            this.Text = "Map / Import - Travel rates";
            Initialize();
        }

        private void partsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            handleCheckOfObjectTypeMenuItem(sender, e);
            if (_Type == AyaType.Part) return;
            _Type = AyaType.Part;
            this.Text = "Map / Import - Parts";
            Initialize();
            if (!util.QBIntegration.Items.Any(z => z.AType == AyaType.Vendor))
            {
                MessageBox.Show(
                "If you plan on importing QuickBooks items into AyaNova parts\r\n" +
                "we recommend you import or link QuickBooks vendors first.\r\n\r\n" +
                "This will ensure items in QuickBooks with a preferred vendor\r\n" +
                "are imported into AyaNova as parts with their Wholesaler field \r\n" +
                "set in AyaNova to a matching QuickBooks vendor",
                    "No QuickBooks vendors are linked");

            }
        }

        private void vendorsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            handleCheckOfObjectTypeMenuItem(sender, e);
            if (_Type == AyaType.Vendor) return;
            _Type = AyaType.Vendor;
            this.Text = "Map / Import - Vendors";
            Initialize();
        }


        private void handleCheckOfObjectTypeMenuItem(object sender, EventArgs e)
        {
            // Set the current clicked item to item
            ToolStripMenuItem item = sender as ToolStripMenuItem;
            // Loop through all items in the subMenu and uncheck them but do check the clicked item
            foreach (ToolStripMenuItem tempItemp in objectToolStripMenuItem.DropDownItems)
            {
                if (tempItemp == item)
                    tempItemp.Checked = true;
                else
                    tempItemp.Checked = false;
            }
        }




        //public class QBNameID
        //{
        //    public string Name { get; set; }
        //    public string ID { get; set; }
        //}

        //List<QBNameID> SelectedQBItems = new List<QBNameID>();

        //public class AyaNameID
        //{
        //    public string Name { get; set; }
        //    public long ID { get; set; }
        //}
        //List<AyaNameID> SelectedAyaItems = new List<AyaNameID>();



        //private bool m_dragging = false;
        //Rectangle dragBoxFromMouseDown;
        //int rowIndexFromMouseDown;
        //int rowIndexOfItemUnderMouseToDrop;


        //private void gridAya_MouseDown(object sender, MouseEventArgs e)
        //{
        //    if (e.Button != MouseButtons.Left)
        //        return;


        //    //Only do this if the user is positioned over a row
        //    rowIndexFromMouseDown = gridAya.HitTest(e.X, e.Y).RowIndex;
        //    if ((rowIndexFromMouseDown != -1))
        //    {
        //        SelectedAyaItems.Clear();
        //        if (gridAya.SelectedRows.Count > 0 && !gridAya.SelectedRows[0].IsNewRow)
        //        {
        //            foreach (DataGridViewRow r in gridAya.SelectedRows)
        //            {
        //                SelectedAyaItems.Add(new AyaNameID { Name = (string)r.Cells[0].Value, ID = (long)r.Cells[1].Value });
        //            }
        //            //Size dragSize = SystemInformation.DragSize;
        //            //dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
        //            m_dragging = true;
        //        }
        //    }
        //    else
        //    {
        //        // dragBoxFromMouseDown = Rectangle.Empty;

        //    }
        //}


        #endregion menu utility stuff



        private void gridAya_CellClick(object sender, DataGridViewCellEventArgs e)
        {

        }



        private void gridQB_CellClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void gridQB_SelectionChanged(object sender, EventArgs e)
        {
            var hasSelection = gridQB.SelectedRows.Count > 0;

            if (hasSelection)
                gridAya.ClearSelection();
        }

        private void gridAya_SelectionChanged(object sender, EventArgs e)
        {
            var hasSelection = gridAya.SelectedRows.Count > 0;

            if (hasSelection)
                gridQB.ClearSelection();
        }







        /*
         * Simplified, no drag and drop just pick and choose with clicks
         * A menu to select the ayanova object type which then populates the ayanova items grid of that type showing:
         A single grid showing all ayanova items of the selected type with their name in the first column and a second column showing what they are mapped to in qb item name, easy peasy, no drag and drop
        User can select one or more items
            when one or more are selected 
                a menu item appears saying "MAP Selected items" when they select they can pick a qb item of the type they want and accept in a popup dialog which also shows how many ayanova items are selected
                a menyu tiem apepars saying UNMAP selected items when they select it it removes the mapping after confirmation dialog from all selected items

            //public static List<InvoiceableItem> GetInvoiceableItems()
        //{
        //    var random = new Random();
        //    var l = new List<InvoiceableItem>();
        //    for (int i = 1; i < random.Next(25, 100); i++)
        //        l.Add(new InvoiceableItem { Customer = $"Customer {random.Next(1, 5)}", Linked = random.Next(2) == 1, Project = $"project {i}", ServiceDate = DateTime.Now.ToString("g"), ServiceNumber = (40 + i).ToString(), Status = $"Waiting to be invoiced", StatusColor = "FF00FFAA", WorkorderId = 4 });

        //    return l.OrderBy(x => x.Customer)
        //                            .ThenBy(x => x.ServiceNumber)
        //                            .ThenBy(x => x.ServiceDate)
        //                            .ToList();

        //}
         
         */
    }
}
