using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using AdvertisingProfitControlData;

namespace DataTableParsingEngine
{
    public class RowParser
    {
        /// <summary>
        /// Clears and rebuilds the ad special list that is held in memory.
        /// This is important as this prevents this engine from grabbing the
        /// list from the database every time this class is called. Otherwise,
        /// there would be noticeable lag getting the list from the SQL server.
        /// </summary>
        public static void BuildAdSpecialListings()
        {
            AdSpecialGroups.Clear();
            var db = new AdvertisingProfitControlDbContext();
            AdSpecialGroups.AddRange(db.AdSpecials.Select(x => x.Name));
        }

        private static readonly List<string> AdSpecialGroups = new List<string>();

        private static string CheckForGroupKeyWord(string cellContents)
        {
            var keyWord = string.Empty;

            var query = from adI in AdSpecialGroups
                        where adI.Equals(cellContents, StringComparison.InvariantCultureIgnoreCase)
                        select adI;

            var enumerable = query as string[] ?? query.ToArray();
            if (enumerable.ToArray().Length > 0)
            {
                //Grab the first object in the array and return it.
                keyWord = enumerable.ToArray().First();
            }

            return keyWord;
        }
        /// <summary>
        /// Determines a row's status.
        /// </summary>
        /// <param name="row">The row from a DataGridView object to be examined.</param>
        /// <returns>The row's status, such as HeaderRow or NewRow.</returns>
        public RowAttribute GetRowAttribute(DataGridViewRow row)
        {
            //IF the supplied row is null, then simply declare it an IncompleteRow.
            if (row == null)
            {
                return RowAttribute.IncompleteRow;
            }
            //IF the supplied row is a new row, by the definition of the DataGridViewRow class, then return NewRow.
            if (row.IsNewRow)
            {
                return RowAttribute.NewRow;
            }
            //Determine the range to use during the looping process.
            var headerCellIndex = row.Cells.Count == Enum.GetNames(typeof(TableGroupParser.SalesTableColumns)).Length ? (int)TableGroupParser.SalesTableColumns.IsHeaderRow : (int)TableGroupParser.InventoryTableColumns.IsHeaderRow;
            var rowContents = new List<string>();
            var rowAttribute = RowAttribute.MemberRow;
            //Get the contents of the row that's being examined and add then to a List<string> array.
            var i = 0;
            foreach (DataGridViewCell cell in row.Cells)
            {
                if (cell.ColumnIndex >= headerCellIndex || cell.ColumnIndex == 0) { i++; continue; }
                //Strip all whitespace characters from the cell, this includes vertical tabs, newlines, and any number of spaces.
                var cellContentsStripped = new string(cell.EditedFormattedValue.ToString().Where(c => !char.IsWhiteSpace(c)).ToArray());
                //Now remove all zeros, including any decimal points as these values are meaningless.
                cellContentsStripped = cellContentsStripped.Replace("0", "");
                cellContentsStripped = cellContentsStripped.Replace(".", "");
                if (cellContentsStripped != "")
                {
                    rowContents.Add(cell.EditedFormattedValue.ToString());
                }
                //If the first cell contains nothing, then return as IncompleteRow.
                else if (cellContentsStripped == "" && i == (int)TableGroupParser.SalesTableColumns.AdItem)
                {
                    return RowAttribute.IncompleteRow;
                }
                i++;
            }

            //With all meaningless content removed, only actual data should be here. So if there are more then one items, than that means there are more then one
            //cells with meaningful data in them. Which means that this row can be a header row with member rows under it.
            if (rowContents.Count > 1)
            {
                rowAttribute = RowAttribute.HeaderRow;
            }
            else if (rowContents.Count == 1) //Check to see if this row is intended to be for a special ad.
            {
                var keyWord = CheckForGroupKeyWord(rowContents[0]);
                //IF a keyword is found then declare this row an AdSpecialRow.
                if (keyWord != string.Empty)
                {
                    return RowAttribute.AdSpecialRow;
                }
            }

            return rowAttribute;
        }

        public enum RowAttribute
        {
            NewRow = 0,
            IncompleteRow = 1,
            AdSpecialRow = 2,
            RepeatedRow = 3,
            MemberRow = 4,
            HeaderRow = 5,
            UnAssigned = 6
        }
    }
}
