/*UC7:- bility to ensure there is no Duplicate Entry of the same Person in a particular Address Book
         *              - Duplicate Check is done on Person Name while adding person to Address Book.
         *              - Use Collection Methods to Search Person by Name for Duplicate Entry.
         *              - Override equals method to check for Duplicate.
         */
        public void AddContact()                    //Create AddContact method to add Record
        {
            Console.Write("Enter First Name:- ");   //Take input
            firstName = Console.ReadLine();         //Store firstname
            Console.Write("Enter Last Name:- ");    //Take input
            lastName = Console.ReadLine();
            Console.Write("Enter The Address ");    //Take input
            address = Console.ReadLine();
            Console.Write("Enter City:- ");         //Take input
            city = Console.ReadLine();
            Console.Write("Enter State:- ");        //Take input
            state = Console.ReadLine();
            Console.Write("Enter Zip Code:- ");     //Take input
            zip = Console.ReadLine();
            Console.Write("Enter Phone Number:- "); //Take input
            phoneNumber = Console.ReadLine();
            Console.Write("Enter Email:- ");        //Take input
            email = Console.ReadLine();
            // Creating an instance of contact with given details
            ContactDetails addNewContact = new ContactDetails(firstName, lastName, address, city, state, zip, phoneNumber, email, nameOfAddressBook);

            while (addNewContact.Equals(contactList))
            {
                Console.WriteLine("contact already exists");
                // Giving option to user to re enter or to exit
                Console.Write("1.Enter New Name\n0.Exit\nEnter Choice:- ");
                int opt = Convert.ToInt32(Console.ReadLine());
                if (opt == 1)
                {
                    Console.WriteLine("Enter new First name");
                    firstName = Console.ReadLine();
                    Console.WriteLine("Enter new Last name");
                    lastName      = Console.ReadLine();
                    addNewContact = new ContactDetails(firstName, lastName, address, city, state, zip, phoneNumber, email, nameOfAddressBook);
                }
                else
                {
                    return;
                }
            }

            contactList.Add(addNewContact);                                // Adding the contact to list
            AddressBookDetails.AddToCityDictionary(city, addNewContact);   // Adding contact to city dictionary
            AddressBookDetails.AddToStateDictionary(state, addNewContact); // Adding contact to state dictionary
            Console.WriteLine("\nContact Added successfully");
        }
        /// <summary>
        /// Adds the contact.
        /// </summary>
        public void AddContact()
        {
            // Getting FirstName
            Console.WriteLine("\nEnter The First Name of Contact");
            firstName = Console.ReadLine();

            // Getting lastName
            Console.WriteLine("\nEnter The Last Name of Contact");
            lastName = Console.ReadLine();

            // Getting Address
            Console.WriteLine("\nEnter The Address of Contact");
            address = Console.ReadLine();

            // Getting city name
            Console.WriteLine("\nEnter The City Name of Contact");
            city = Console.ReadLine().ToLower();

            // Getting state name
            Console.WriteLine("\nEnter The State Name of Contact");
            state = Console.ReadLine().ToLower();

            // Getting zip of locality
            Console.WriteLine("\nEnter the Zip of Locality of Contact");
            zip = Console.ReadLine();

            // Getting Phone number
            Console.WriteLine("\nEnter The Phone Number of Contact");
            phoneNumber = Console.ReadLine();

            // Getting Email of contact
            Console.WriteLine("\nEnter The Email of Contact");
            email = Console.ReadLine();

            // Creating an instance of contact with given details
            ContactDetails addNewContact = new ContactDetails(firstName, lastName, address, city, state, zip, phoneNumber, email, nameOfAddressBook);

            // Checking for duplicates with the equals method
            // Loop continues till the given contact doesnt equal to any available contact
            while (addNewContact.Equals(contactList))
            {
                Console.WriteLine("contact already exists");
                logger.Error("User tried to create a duplicate of contact");

                // Giving option to user to re enter or to exit
                Console.WriteLine("Type Y to enter new name or any other key to exit");

                // If user wants to re-enter then taking input from user
                // Else return
                if ((Console.ReadLine().ToLower() == "y"))
                {
                    Console.WriteLine("Enter new first name");
                    firstName = Console.ReadLine();
                    Console.WriteLine("Enter new last name");
                    lastName      = Console.ReadLine();
                    addNewContact = new ContactDetails(firstName, lastName, address, city, state, zip, phoneNumber, email, nameOfAddressBook);
                }
                else
                {
                    return;
                }
            }

            // Adding the contact to list
            contactList.Add(addNewContact);

            // Adding contact to city dictionary
            AddressBookDetails.AddToCityDictionary(city, addNewContact);

            // Adding contact to state dictionary
            AddressBookDetails.AddToStateDictionary(state, addNewContact);
            Console.WriteLine("\nContact added successfully");
        }
        public void EditContact() //Create EditContact method to edite record
        {
            try
            {
                if (contactList.Count() == 0)               //List have no contacts
                {
                    Console.WriteLine(" Record Not Found"); //print
                    return;
                }
                Console.Write("Enter First Name :- ");              //Take First Name
                string         name    = Console.ReadLine();
                ContactDetails contact = SearchByName(name);        // Search the name

                if (contact == null)                                // If contact doesnt exist
                {
                    Console.WriteLine($"{name } Record Not Found"); //Print
                    return;
                }

                contact.Display();  //  print record of searched contact

                int updateAttributeNum = 0;
                Console.Write("Enter Row number Record to be Edit:- "); //print and take input
                try
                {
                    updateAttributeNum = Convert.ToInt32(Console.ReadLine());
                    if (updateAttributeNum == 0)
                    {
                        return;
                    }
                }
                catch
                {
                    Console.WriteLine("Invalid entry");
                    return;
                }
                Console.Write("Enter the New Record:- "); // Take input
                string newValue = Console.ReadLine();
                switch (updateAttributeNum)               // Updating selected attribute with selected value
                {
                case UPDATE_FIRST_NAME:
                    firstName         = contact.FirstName; // Store the firstname of contact in variable
                    contact.FirstName = newValue;          // Update the contact with given name
                    if (contact.Equals(contactList))       // If duplicate contact exists with that name then revert the operation
                    {
                        contact.FirstName = firstName;
                        Console.Write($"Contact already exists that{ contact.FirstName} Name");
                        return;
                    }
                    break;

                case UPDATE_LAST_NAME:
                    lastName         = contact.LastName; // Store the LastName of given contact in variable
                    contact.LastName = newValue;         // Update the contact with given name
                    if (contact.Equals(contactList))     // If duplicate contact exists with that name then revert the operation
                    {
                        contact.LastName = lastName;
                        Console.WriteLine($"Contact already exists with that {contact.LastName} name");
                        return;
                    }
                    break;

                case UPDATE_ADDRESS:
                    contact.Address = newValue;
                    break;

                case UPDATE_CITY:
                    AddressBookDetails.cityToContactMap[contact.City].Remove(contact); // Remove the contact from city dictionary
                    contact.City = newValue;                                           // Update the contact city
                    AddressBookDetails.AddToCityDictionary(contact.City, contact);     // Add to city dictionary
                    break;

                case UPDATE_STATE:
                    AddressBookDetails.stateToContactMap[contact.State].Remove(contact); // Remove the contact from state dictionary
                    contact.State = newValue;                                            // Update the contact state
                    AddressBookDetails.AddToStateDictionary(contact.State, contact);     // Add to state dictionary
                    break;

                case UPDATE_ZIP:
                    contact.Zip = newValue;
                    break;

                case UPDATE_PHONE_NUMBER:
                    contact.PhoneNumber = newValue;
                    break;

                case UPDATE_EMAIL:
                    contact.Email = newValue;
                    break;

                default:
                    Console.WriteLine("Invalid Entry");
                    return;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine("Record Successfully Edit and Updated ");
        }
        /// <summary>
        /// Updates the contact.
        /// </summary>
        public void UpdateContact()
        {
            // If the List have no contacts
            if (contactList.Count() == 0)
            {
                Console.WriteLine("No saved contacts");
                return;
            }

            // Input the name to be updated
            Console.WriteLine("\nEnter the name of candidate to be updated");
            string name = Console.ReadLine();

            logger.Info("User tried to update contact" + name);

            // Search the name
            ContactDetails contact = SearchByName(name);

            // If contact doesnt exist
            if (contact == null)
            {
                Console.WriteLine("No record found");
                return;
            }

            // To print details of searched contact
            contact.toString();

            int updateAttributeNum = 0;

            // Getting the attribute to be updated
            Console.WriteLine("\nEnter the row number attribute to be updated or 0 to exit");
            try
            {
                updateAttributeNum = Convert.ToInt32(Console.ReadLine());
                if (updateAttributeNum == 0)
                {
                    return;
                }
            }
            catch
            {
                Console.WriteLine("Invalid entry");
                return;
            }

            // Getting the new value of attribute
            Console.WriteLine("\nEnter the new value to be entered");
            string newValue = Console.ReadLine();

            // Updating selected attribute with selected value
            switch (updateAttributeNum)
            {
            case UPDATE_FIRST_NAME:

                // Store the firstname of given contact in variable
                firstName = contact.FirstName;

                // Update the contact with given name
                contact.FirstName = newValue;

                // If duplicate contact exists with that name then revert the operation
                if (contact.Equals(contactList))
                {
                    contact.FirstName = firstName;
                    Console.WriteLine("Contact already exists with that name");
                    return;
                }
                break;

            case UPDATE_LAST_NAME:

                // Store the LastName of given contact in variable
                lastName = contact.LastName;

                // Update the contact with given name
                contact.LastName = newValue;

                // If duplicate contact exists with that name then revert the operation
                if (contact.Equals(contactList))
                {
                    contact.LastName = lastName;
                    Console.WriteLine("Contact already exists with that name");
                    return;
                }
                break;

            case UPDATE_ADDRESS:
                contact.Address = newValue;
                break;

            case UPDATE_CITY:

                // Remove the contact from city dictionary
                AddressBookDetails.cityToContactMap[contact.City].Remove(contact);

                // Update the contact city
                contact.City = newValue;

                // Add to city dictionary
                AddressBookDetails.AddToCityDictionary(contact.City, contact);
                break;

            case UPDATE_STATE:

                // Remove the contact from state dictionary
                AddressBookDetails.stateToContactMap[contact.State].Remove(contact);

                // Update the contact state
                contact.State = newValue;

                // Add to state dictionary
                AddressBookDetails.AddToStateDictionary(contact.State, contact);
                break;

            case UPDATE_ZIP:
                contact.Zip = newValue;
                break;

            case UPDATE_PHONE_NUMBER:
                contact.PhoneNumber = newValue;
                break;

            case UPDATE_EMAIL:
                contact.Email = newValue;
                break;

            default:
                Console.WriteLine("Invalid Entry");
                return;
            }
            logger.Info("User updated contact");
            Console.WriteLine("\nUpdate Successful");
        }