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

namespace pmsDataGridView
{
    public partial class SaleEditForm_v2 : Form
    {
        public enum OrderItemsColumnType { ITEM, DESCRIPTION, QUANTITY, COST, PRICE}
        public SaleEditForm_v2()
        {
            InitializeComponent();
			SaleInfoTtextBox11.BackColor = Color.Black;
			SaleInfoTtextBox12.BackColor = Color.Black;
            SaleSourceDropDownBox.SelectedIndex = (int) SaleRecord.SaleSourceType.TRADEME; //show trade me as default
        }

        public SaleEditForm_v2(ProductList OrderedBearings, CustomerList customerlist)
            : this() //call the constructor without argument first
        {
            this.customerlist = customerlist;
            ordered_bearings = OrderedBearings;
            
            //display info
            //SaleInfoTtextBox.AppendText("Total Item Quantity: " + ordered_bearings.TotalNumberOfBearings.ToString());

            //fill SaleItemGrid grid
            fill_grid();

            //set some internal variables (initial, maybe changed later)
            if (InitConfig.Business == InitConfig.BusinessType.BEARING)
            {
                ShippingCost = 1.10;
                PromotionCost = 0.50;                
                /*
                if (ordered_bearings.TotalNumberOfBearings >= 20)
                {
                    ShippingPayable = 0;
                    if (ordered_bearings.TotalNumberOfBearings >= 200)
                    {
                        Discount = 15;
                    }
                    else if (ordered_bearings.TotalNumberOfBearings >= 100)
                    {
                        Discount = 10;
                    }
                    else
                    {
                        Discount = 0;
                    }
                }
                else
                {
                    ShippingPayable = 3.50;
                    Discount = 0;
                } 
                 * */
                ShippingPayable = 3.50;
                Discount = 0;
            }
            if (InitConfig.Business == InitConfig.BusinessType.ELECTRONICS)
            {
                double trademe_rate = 0.075;
                ShippingCost = 3.50;                
                ShippingPayable = 4.50; //by default the sale is from trade me
                //ShippingPayable = 0;
                Discount = 0;                
                PromotionCost = productsPayable() * trademe_rate;
                if (PromotionCost < 0.50) //if less than 50 cents, trade me charges a minimum of 50 cent
                {
                    PromotionCost = 0.50;
                }
            }
            //prefill some boxes
            ShippingCostTestBox.Text = ShippingCost.ToString("0.00");
            PromotionCostTexBox.Text = PromotionCost.ToString("0.00");
            ShippingPayableTexBox.Text = ShippingPayable.ToString("0.00");
            DiscountTextBox.Text = Discount.ToString();
            update_TotalPayable();
            if (InitConfig.Business == InitConfig.BusinessType.ELECTRONICS)
            {
                //update the promotional cost according to the new product payable
                update_trademe_cost();
            }
        }

        public void update_trademe_cost()
        {
            double trademe_rate = 0.075;
            PromotionCost = productsPayable() * trademe_rate;
            if (PromotionCost < 0.50) //if less than 50 cents, trade me charges a minimum of 50 cent
            {
                PromotionCost = 0.50;
            }
            PromotionCostTexBox.Text = PromotionCost.ToString("0.00");
        }
        //constructor for editmode
        public SaleEditForm_v2(SaleRecord s, int selected_row_index, CustomerList customerlist)
            : this()
        {
            this.customerlist = customerlist;
            this.selected_row_index = selected_row_index;
            sale = s;
            ordered_bearings = s.BearingOrder;
            customer = customerlist[s.CustomerIndex];
            fill_grid();

            TotalPayable = s.Payable;
            ShippingCost = s.ShippingCost;
            ShippingPayable = s.ShippingPayable;
            PromotionCost = s.PromotionCost;
            Discount = s.Discount;
            Discount_amount = s.Discount_amount;

            //fill up the text boxes
            ShippingCostTestBox.Text = ShippingCost.ToString("0.00");
            ShippingPayableTexBox.Text = ShippingPayable.ToString("0.00");
            PromotionCostTexBox.Text = PromotionCost.ToString("0.00");
            DiscountTextBox.Text = Discount.ToString();
            SaleCommentTextBox.Text = s.Comment;
            EmailTextBox.Text = customerlist[s.CustomerIndex].Email;
            EditMode = true;
        }

        public void fill_grid()
        {
            for (int i = 0; i < ordered_bearings.Count; i++)
            {
                SaleItemGrid.Rows.Add();
                fill_a_item_to_row_i(ordered_bearings[i], i);
            }
        }
        public void update_TotalPayable()
        {
            //grab info from all text boxes
            ShippingPayable = Convert.ToDouble(ShippingPayableTexBox.Text);
            ShippingCost = Convert.ToDouble(ShippingCostTestBox.Text);
            PromotionCost = Convert.ToDouble(PromotionCostTexBox.Text);
            Discount = Convert.ToInt32(DiscountTextBox.Text);

            TotalPayable = 0; //initialize it first
            TotalPayable = productsPayable();

            Discount_amount = TotalPayable * Discount * 0.01;
            TotalPayable = TotalPayable - Discount_amount;
            TotalPayable += ShippingPayable;
        }

        public double productsPayable() //only the products, excludes shipping and discount
        {
            double pPayable = 0;
            for (int i = 0; i < ordered_bearings.Count; i++)
            {
                pPayable += ordered_bearings[i].Price * ordered_bearings[i].quantity;
            }
            return pPayable;
        }
        private void fill_a_item_to_row_i(Product b, int i)
        {
            SaleItemGrid.Rows[i].Cells[(int)OrderItemsColumnType.ITEM].Value = b.name;
            SaleItemGrid.Rows[i].Cells[(int)OrderItemsColumnType.DESCRIPTION].Value = b.Desription;
            SaleItemGrid.Rows[i].Cells[(int)OrderItemsColumnType.QUANTITY].Value = b.quantity.ToString();
            SaleItemGrid.Rows[i].Cells[(int)OrderItemsColumnType.COST].Value = b.prime_cost.ToString("0.00");
            SaleItemGrid.Rows[i].Cells[(int)OrderItemsColumnType.PRICE].Value = b.Price.ToString("0.00");            
        }


        private void CancelButton_Click(object sender, EventArgs e)
        {
            Hide();
        }

        //auto complete of customer detail by email
        private void EmailTextBox_TextChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < customerlist.Count; i++)
            {
                if (string.Compare(customerlist[i].Email, EmailTextBox.Text.ToString(), true) == 0)
                {// email in the text box mathes the one in customerlist
                    if (string.Compare(customerlist[i].Email, added_customer_email, true) != 0)
                    {// email in the text box not equal to the email of a newly added customer

                        //compare the entered customer email with the customer database, ignore case
                        knowncustomer = true;
                        customer = customerlist[i];
                        //display info
                        //SaleInfoTtextBox.AppendText(c.UserName + Environment.NewLine + c.UserName + Environment.NewLine + c.Address 
                        //    + Environment.NewLine + c.Country + Environment.NewLine + c.Comment );

                        //grab the customer index
                        customer_index = customerlist[i].Index;

                        //display info
                        refresh_info();
                        break;
                    }
                }
            }
        }

        public void refresh_info()
        {    
            StringBuilder sb = new StringBuilder();
            ProductList bl = ordered_bearings;

            //take the changes from the grid for unit price. Can't change the quantity now, so if make mistake just delete the sale
            //and key in another one. The reason is when the order item quantity is change, the quantity in the productlist needs to
            //be updated, but here doen't have the productlist information, so may need to make big change in code.
            
            for (int i = 0; i < ordered_bearings.Count; i++)
            {
                double priceInTextBox;
                bool isNum = double.TryParse(SaleItemGrid.Rows[i].Cells[(int)OrderItemsColumnType.PRICE].Value.ToString(), out priceInTextBox);
                if (isNum)
                {
                    ordered_bearings[i].Price = priceInTextBox;
                    //ordered_bearings[i].Price = Convert.ToDouble(SaleItemGrid.Rows[i].Cells[(int)OrderItemsColumnType.PRICE].Value);
                }
                //do the same thing for the prime cost, when it is changed in the grid
                double costInTextBox;
                isNum = double.TryParse(SaleItemGrid.Rows[i].Cells[(int)OrderItemsColumnType.COST].Value.ToString(), out costInTextBox);
                if (isNum)
                {
                    ordered_bearings[i].prime_cost = costInTextBox;                    
                }
            }


            update_TotalPayable();


            //print out the purchased detail
            sb.Append("Sale detail:" + Environment.NewLine + "Item\tQuantity\tEach\tSubtotal\n");
            
            for (int i = 0; i < bl.Count; i++)
            {
                double subtotal = bl[i].quantity * bl[i].Price;
                sb.Append(bl[i].name + "\t " + bl[i].quantity + "\t" + bl[i].Price.ToString("$0.00") + "\t" + subtotal.ToString("$0.00") + "\n");
            }
            sb.Append("shipping\t\t\t" + ShippingPayable.ToString("$0.00") + "\n");
            if (Discount != 0)
            {
                //double discount_amount = (TotalPayable - ShippingPayable) * (1 - 1 / (1 - sale.Discount * 0.01));//note, payable is already the discounted figure
                sb.Append("discount\t\t" + Discount + "%\t" + Discount_amount.ToString("-$0.00") + "\n");
            }
            sb.Append("\nTotal\t" + ordered_bearings.TotalNumberOfBearings.ToString() + "\t\t" + TotalPayable.ToString("$0.00") + "\n\n");

            //print out sale detail
            SaleInfoTtextBox11.Text = sb.ToString(); 
            //print out customer detail
            if (customer != null)
            {
                SaleInfoTtextBox12.Text = ("Customer detail:" + Environment.NewLine + customer.Name + Environment.NewLine + customer.UserName + Environment.NewLine + customer.Address
                            + Environment.NewLine + customer.Country + Environment.NewLine + customer.Comment + Environment.NewLine);
            }
                    
        }

        private void RefreshButton_Click(object sender, EventArgs e)
        {
            if (customer == null) //don't have customer detail, make it up as unknown
            {
                add_an_unknown_customer();
            }
            refresh_info();
        }

        private void AddCustomerForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            //come back to the mainform after entering a customer detail
            CustomerEditForm addcustomerform = (CustomerEditForm)sender;
            if (addcustomerform.OKpressed)
            {
                //update the added_customer_email to signify a new customer was added, to ensure knowncustomer = false
                added_customer_email = addcustomerform.customer.Email;
                //knowncustomer = false;
                //add the new customer to the customer list
                customerlist.add(addcustomerform.customer);
                //assign the index for the newly added customer
                customerlist[customerlist.Count - 1].Index = customerlist.Count - 1;

                //update the local variables                
                customer_index = customerlist.Count - 1;
                customer = customerlist[customer_index];

                //fill in the email text box in case it wasn't filled in and click 'add customer' directly
                EmailTextBox.Text = customer.Email;

                //display info
                refresh_info();
            }

        }

        public void add_an_unknown_customer()
        {
            customer = new Customer("unknown", "unknown", EmailTextBox.Text, "unknown", "New Zealand", "unknown");
            customer.Index = customerlist.Count;
            customer_index = customerlist.Count;
            customerlist.add(customer);
        }

        private void OkButton_Click(object sender, EventArgs e)
        {
            //lacking customer detail is allowed, it can be provided later
            if (customer == null) //don't have customer detail, make it up as unknown
            {
                add_an_unknown_customer();
            }
             
            //in case the refresh button wasn't pressed
            refresh_info();
            OKpressed = true;

            if (EditMode)
            {
                //update the sale
                sale.ShippingPayable = ShippingPayable;
                sale.ShippingCost = ShippingCost;
                sale.PromotionCost = PromotionCost;
                sale.Discount = Discount;
                sale.Discount_amount = Discount_amount;
                sale.CustomerIndex = customer_index;
                sale.Comment = SaleCommentTextBox.Text;
                sale.updatePayable();
                sale.updateRevenue();
                sale.Source = (SaleRecord.SaleSourceType)SaleSourceDropDownBox.SelectedIndex;
            }
            else
            {
                sale = new SaleRecord(ShippingPayable, ShippingCost, PromotionCost, ordered_bearings, customer_index, Discount, SaleCommentTextBox.Text);
                // newly added field
                sale.Source = (SaleRecord.SaleSourceType)SaleSourceDropDownBox.SelectedIndex;
            }

           //if its a sale from the website, by default it is paid. 
            if ((SaleRecord.SaleSourceType)SaleSourceDropDownBox.SelectedIndex == SaleRecord.SaleSourceType.WEBSITE)
            {
                sale.Paid = true;
            }
           
            Close();
        }

        private void AddCustomerButton_Click(object sender, EventArgs e)
        {
            if (customer == null)
            {
                CustomerEditForm AddCustomer = new CustomerEditForm(EmailTextBox.Text);
                AddCustomer.Show();
                AddCustomer.FormClosed += new FormClosedEventHandler(AddCustomerForm_FormClosed);
            }
        }

        public SaleRecord sale;
        public Customer customer = null;
        public ProductList ordered_bearings;
        public CustomerList customerlist;
        public double ShippingCost;
        public double PromotionCost;
        public int Discount = 0; //%
        public double Discount_amount = 0;
        public double ShippingPayable;
        public double TotalPayable = 0;
        public bool knowncustomer = false;
        public bool OKpressed = false;
        public int customer_index = -1;
        public bool EditMode = false;
        public int selected_row_index=-1;
        public bool Customer_added = false;
        public string added_customer_email;

        private void SaleSourceDropDownBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch ((SaleRecord.SaleSourceType)SaleSourceDropDownBox.SelectedIndex )
            {
                case SaleRecord.SaleSourceType.WEBSITE:
                    //free shipping only applies for Electronci business
                    if (InitConfig.Business == InitConfig.BusinessType.ELECTRONICS)
                    {
                        ShippingPayableTexBox.Text = "0";
                    }
                    PromotionCostTexBox.Text = "0";
                    break;
                case SaleRecord.SaleSourceType.TRADEME:
                    break;
            }            

        }

    }
}
