using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using Baza_Reklam.Classes.Helpers;
using Baza_Reklam.Classes.Model;
using Baza_Reklam.Classes.Repositories;

namespace Baza_Reklam
{
    public partial class AddClient : Form
    {
        private readonly int _clientId;
        private REKLAMADataSet.KLIENCIRow _client;
        private bool _reload;

        public REKLAMADataSet.KLIENCIRow Client
        {
            get { return _client; }
        }

        public bool Reload
        {
            get { return _reload; }
            set { _reload = value; }
        }

        public AddClient()
        {
            InitializeComponent();
            Init();
        }

        public AddClient(int clientId, BindingSource bindingSource)
        {
            InitializeComponent();
            rEKLAMADataSet = (REKLAMADataSet)bindingSource.DataSource;
            clientsBindingSource = bindingSource;
            _clientId = clientId;
            
            // rebind controls to use passed binding source
            ReBindControls(this, clientsBindingSource);
            
            Init();
        }

        private void Init()
        {
            LoadTitleList();
            clientsAdapter.Connection.ConnectionString = ConnString.getConnString().Value;
            clientTitlesAdapter.Connection.ConnectionString = ConnString.getConnString().Value;

            BindComboBox(CountryRepository.FindAll(), cbCountry);
            cbCountry.DisplayMember = "Name";
            cbCountry.ValueMember = "Name";

            BindComboBox(StateRepository.FindAll(), cbState);
            cbState.DisplayMember = "Name";
            cbState.ValueMember = "Name";

            BindComboBox(new AgentRepository().FindAllActive(), cbUserName);
            cbUserName.DisplayMember = "LoginName";
            cbUserName.ValueMember = "LoginName";

            BindComboBox(new AgentRepository().FindAllActive(), cbAgentExpo);
            cbAgentExpo.DisplayMember = "LoginName";
            cbAgentExpo.ValueMember = "LoginName";
        }

        private void AddClient_Load(object sender, EventArgs e)
        {
            Reload = false;
            bool update = false;
            if (_clientId == 0) // add new client
            {
                _client = rEKLAMADataSet.KLIENCI.NewKLIENCIRow();
                _client.Last_Modify = DateTime.Now;
                _client.data = DateTime.Now;
                _client.UserName = User.Instance().Login;
                _client.AgentExpo = User.Instance().Login;
                rEKLAMADataSet.KLIENCI.AddKLIENCIRow(_client);
                clientsBindingSource.MoveLast();
                cbCountry.SelectedIndex = -1;
                cbState.SelectedIndex = -1;
                cbActive.Checked = true;
            }
            else // update selected client
            {
                update = true;
                _client = (REKLAMADataSet.KLIENCIRow)((DataRowView)clientsBindingSource.Current).Row;

                InitClientTitles();
            }

            SetStateUserNameAndAgentExpo(_client, update);

            SetFormCaption(update);

        }

        private void InitClientTitles()
        {
            clientTitlesAdapter.FillByCustomerId(rEKLAMADataSet.KLIENCI_TYTUL, _client.CustomerID);

            lbClientTitles.DataSource = rEKLAMADataSet.KLIENCI_TYTUL;
            lbClientTitles.DisplayMember = rEKLAMADataSet.KLIENCI_TYTUL.TYTULColumn.ColumnName;
            lbClientTitles.ValueMember = rEKLAMADataSet.KLIENCI_TYTUL.ID_KLIENCI_TYTULColumn.ColumnName;
        }

        private void SetFormCaption(bool update)
        {
            Text = update ? "Edytuj dane klienta" : "Dodaj klienta";
        }

        private void SetStateUserNameAndAgentExpo(REKLAMADataSet.KLIENCIRow client, bool update)
        {
            if (update)
            {
                if (!client.IsStateNull())
                {
                    int stateIndex = cbState.FindString(client.State);
                    if (stateIndex < 0)
                    {
                        cbState.Items.Insert(0, new State(client.State));
                        cbState.SelectedIndex = 0;
                    }
                }

                int userNameIndex = cbUserName.FindString(client.UserName);
                if (userNameIndex < 0)
                    cbUserName.Items.Insert(0, new Agent(client.UserName.Trim().ToLower()));

                int agentExpoIndex = cbAgentExpo.FindString(client.AgentExpo);
                if (agentExpoIndex < 0)
                    cbAgentExpo.Items.Insert(0, new Agent(client.AgentExpo.Trim().ToLower()));
            }

            cbUserName.SelectedIndex = cbUserName.FindString(client.UserName.Trim().ToLower());
            cbAgentExpo.SelectedIndex = cbAgentExpo.FindString(client.AgentExpo.Trim().ToLower());

            cbUserName.Enabled = (DbUtils.idAgencji(client.UserName) == User.Instance().IdAgencji);
            cbAgentExpo.Enabled = (DbUtils.idAgencji(client.AgentExpo) == User.Instance().IdAgencji);
            if (!User.Instance().St_kierownik)
            {
                cbUserName.Enabled = client.UserName.Trim().ToLower() == User.Instance().Symbol_agenta.Trim().ToLower();
                cbAgentExpo.Enabled = client.AgentExpo.Trim().ToLower() == User.Instance().Symbol_agenta.Trim().ToLower();
            }
        }

        private static void ReBindControls(Control control, BindingSource bindingSource)
        {
            foreach (Control ctrl in control.Controls)
            {
                if (ctrl.DataBindings.Count == 1)
                {
                    string property = ctrl.DataBindings[0].PropertyName;
                    string dataMember = ctrl.DataBindings[0].BindingMemberInfo.BindingField;

                    ctrl.DataBindings.Clear();
                    ctrl.DataBindings.Add(property, bindingSource, dataMember, true);
                    Debug.WriteLine(ctrl.Name + ": " + ctrl.DataBindings[0].PropertyName + "; " + ctrl.DataBindings[0].BindingMemberInfo.BindingField);
                }

                ReBindControls(ctrl, bindingSource);
            }
        }

        private void LoadTitleList()
        {
            SLOWNIKDataSetTableAdapters.LISTA_TYTULOWTableAdapter titleListAdapter = new SLOWNIKDataSetTableAdapters.LISTA_TYTULOWTableAdapter();
            titleListAdapter.Connection.ConnectionString = ConnString.getConnString().Value;
            lbTitles.DataSource = titleListAdapter.GetData();
            lbTitles.DisplayMember = "SYMB";
            lbTitles.ValueMember = "SYMB";
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (ValidateChildren())
            {
                Cursor = Cursors.WaitCursor;

                Client.Last_Modify = DateTime.Now;
                Client.Modify_User = User.Instance().Login;
                clientsBindingSource.EndEdit();
                clientsAdapter.Update(rEKLAMADataSet.KLIENCI);
                Cursor = Cursors.Default;
                Reload = true;
                Close();
                return;
            }
            Reload = false;
            MessageBox.Show("Proszę wprowadzić wszystkie wymagane dane.");
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            rEKLAMADataSet.KLIENCI.RejectChanges();
            Close();
        }

        private void btnCopyAddress_Click(object sender, EventArgs e)
        {
            List<string> address = new List<string>();
            address.Add(txtName1.Text);
            address.Add(txtAddress.Text);
            address.Add(txtPostCode.Text + " " + txtCity.Text);
            if (!string.IsNullOrEmpty(cbState.Text.Trim()))
                address.Add(cbState.Text);

            address.Add(cbCountry.Text);

            txtInvoiceAddress.Lines = address.ToArray();
            txtCorespondenceAddress.Lines = address.ToArray();
        }

        private void btnAddTitle_Click(object sender, EventArgs e)
        {
            if (lbTitles.SelectedValue == null)
            {
                MessageBox.Show("Proszę wybrać tytuł do dodania");
                return;
            }

            clientTitlesAdapter.Insert(lbTitles.SelectedValue.ToString(), _client.CustomerID, User.Instance().Login, DateTime.Now);
            clientTitlesAdapter.FillByCustomerId(rEKLAMADataSet.KLIENCI_TYTUL, _client.CustomerID);

        }

        private void btnRemoveTitle_Click(object sender, EventArgs e)
        {
            if (lbClientTitles.SelectedItem == null) return;

            DataRow row = rEKLAMADataSet.KLIENCI_TYTUL.Select(rEKLAMADataSet.KLIENCI_TYTUL.ID_KLIENCI_TYTULColumn.ColumnName + "=" + lbClientTitles.SelectedValue)[0];
            row.Delete();
            clientTitlesAdapter.Update(rEKLAMADataSet.KLIENCI_TYTUL);
        }

        private void txtName1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        {
            ValidationHelper.IsTextBoxEmpty(txtName1, "Proszę podać nazwę klienta.", e, errorProvider);
        }

        private void cbCountry_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        {
            ValidationHelper.IsComboValueSelected(cbCountry, "Proszę wybrać kraj klienta.", e, errorProvider);
        }

        private void txtCity_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        {
            ValidationHelper.IsTextBoxEmpty(txtCity, "Proszę podać miasto klienta.", e, errorProvider);
        }

        private void txtClientCode_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (string.IsNullOrEmpty(txtClientCode.Text)) return;

            StringBuilder sb = new StringBuilder();

            if (!DbUtils.kodKlientaUnikalny(txtClientCode.Text, Client.UserName, Client.CustomerID))
            {
                e.Cancel = true;
                sb.Append("Proszę podać inny kod klienta. Podany kod już istnieje dla wybranego agenta.");
            }
            else
                e.Cancel = false;

            errorProvider.SetError(txtClientCode, sb.ToString());
        }

        void BindComboBox<T>(IEnumerable<T> list, ComboBox comboBox)
        {
            comboBox.Items.Clear();
            foreach (T item in list)
            {
                comboBox.Items.Add(item);
            }
        }
    }
}