using ContactManagementSystem.Data;
using ContactManagementSystem.Data.Repositories;
using ContactManagementSystem.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using static System.Net.Mime.MediaTypeNames;

namespace ContactManagementSystem
{
    /// <summary>
    /// Main program for Contact Management System - Day 1 Version
    /// Demonstrates: Basic console application, Collections, LINQ basics
    /// </summary>
    class Program
    {
        static async Task Main(string[] args)
        {
            // header
            await MyHeader();

            // Test the database connection
            // await TestDatabaseConnection();

            // Demonstrates Repositories using Contacts
            await DemoRepository();

            // footer
          //  Console.WriteLine("\nPress any key to exit...");
           // Console.ReadKey();
        } // Main

        /// <summary>
        ///  Demo for Repositories
        /// </summary>
        /// <returns></returns>
        /// 
        static async Task DemoRepository()
        {
            using (var repository = new ContactRepository())
            {
                try
                {
                    // Test 1: Get all contacts
                    Console.WriteLine("1. Getting all contacts...");
                    var contacts = await repository.GetAllAsync();
                    Console.WriteLine($"   Found {contacts.Count} contacts\n");

                    // Test 2: Get favorites
                    Console.WriteLine("2. Getting favorite contacts...");
                    var favorites = await repository.GetFavoritesAsync();
                    Console.WriteLine($"   Found {favorites.Count} favorites:");
                    foreach (var fav in favorites)
                    {
                        Console.WriteLine($"   - {fav.FirstName} {fav.LastName}");
                    }
                    Console.WriteLine();

                    // Test 3: Search
                    Console.WriteLine("3. Searching for 'Tech'...");
                    var searchResults = await repository.SearchAsync("Tech");
                    Console.WriteLine($"   Found {searchResults.Count} matches:");
                    foreach (var result in searchResults)
                    {
                        Console.WriteLine($"   - {result.FirstName} {result.LastName} - {result.Company}");
                    }
                    Console.WriteLine();

                    // Test 4: Add new contact
                    Console.WriteLine("4. Adding new contact...");
                    var newContact = new Contact
                    {
                        FirstName = "Test",
                        LastName = "User",
                        Email = "test.user@example.com",
                        PhoneNumber = "5155559999",
                        Company = "Test Corp",
                        IsFavorite = false
                    };
                    var added = await repository.AddAsync(newContact);
                    Console.WriteLine($"   Added: {added.FirstName} {added.LastName} (ID: {added.Id})\n");

                    // Test 5: Update contact
                    Console.WriteLine("5. Updating contact...");
                    added.IsFavorite = true;
                    added.Company = "Updated Corp";
                    bool updated = await repository.UpdateAsync(added);
                    Console.WriteLine($"   Updated: {updated}\n");

                    // Test 6: Get by ID
                    Console.WriteLine("6. Getting contact by ID...");
                    var retrieved = await repository.GetByIdAsync(added.Id);
                    Console.WriteLine($"   Retrieved: {retrieved.FirstName} {retrieved.LastName}");
                    Console.WriteLine($"   Company: {retrieved.Company}");
                    Console.WriteLine($"   Favorite: {retrieved.IsFavorite}\n");

                    /*
                    // Test 7: Delete contact
                    Console.WriteLine("7. Deleting test contact...");
                    bool deleted = await repository.DeleteAsync(added.Id);
                    Console.WriteLine($"   Deleted: {deleted}\n");

                    // Test 8: Get count
                    Console.WriteLine("8. Getting total count...");
                    int count = await repository.GetCountAsync();
                    Console.WriteLine($"   Total contacts: {count}\n");
                    */
                    Console.WriteLine("✓ All repository tests completed!");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"\n✗ Error: {ex.Message}");
                }
            }
        }



        static async Task MyHeader()
        {

            try
            {
                Console.WriteLine("===========================================");
                Console.WriteLine("  Contact Management System - Day 3 Test");
                Console.WriteLine("===========================================\n");
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.ToString());

            }


        } // MyHeader()

        /// <summary>
        /// Tests the database connection and performs simple queries
        /// </summary>
        static async Task TestDatabaseConnection()
        {
            try
            {
                using (var context = new ApplicationDbContext())
                {
                    Console.WriteLine("Testing database connection...");

                    // Test 1: Can we connect?
                    bool canConnect = await context.Database.CanConnectAsync();

                    if (canConnect)
                    {
                        Console.WriteLine("✓ Database connection successful!\n");
                        // throws day 1
                    }
                    else
                    {
                        Console.WriteLine("✗ Cannot connect to database\n");
                        return;
                    }

                    // Test 2: Count total contacts
                    Console.WriteLine("Running queries...\n");

                    int totalContacts = await context.Contacts.CountAsync();
                    Console.WriteLine($"✓ Total contacts in database: {totalContacts}");

                    // Test 3: Get all contacts
                    var contacts = await context.Contacts.ToListAsync();
                    Console.WriteLine($"✓ Retrieved {contacts.Count} contact(s)\n");

                    // Test 4: Display all contacts
                    if (contacts.Any())
                    {
                        Console.WriteLine("Contact List:");
                        Console.WriteLine(new string('-', 80));
                        Console.WriteLine("{0,-5} {1,-15} {2,-15} {3,-30} {4,-10}",
                            "ID", "First Name", "Last Name", "Email", "Favorite");
                        Console.WriteLine(new string('-', 80));

                        foreach (var contact in contacts)
                        {
                            Console.WriteLine("{0,-5} {1,-15} {2,-15} {3,-30} {4,-10}",
                                contact.Id,
                                contact.FirstName,
                                contact.LastName,
                                contact.Email,
                                contact.IsFavorite ? "Yes" : "No");
                        }
                        Console.WriteLine(new string('-', 80));
                    }
                    else
                    {
                        Console.WriteLine("No contacts found in database.");
                    }

                    // Test 5: Get favorite contacts LINQ
                    Console.WriteLine();
                    var favoriteContacts = await context.Contacts
                        .Where(c => c.IsFavorite)
                        .ToListAsync();

                    Console.WriteLine($"✓ Favorite contacts: {favoriteContacts.Count}");

                    if (favoriteContacts.Any())
                    {
                        foreach (var contact in favoriteContacts)
                        {
                            Console.WriteLine($"  - {contact.FirstName} {contact.LastName} ({contact.Company})");
                        }
                    }
                    /*
                    // Test 6: Get contacts by company
                    Console.WriteLine();
                    var techCorpContacts = await context.Contacts
                        .Where(c => c.Company == "Tech Corp")
                        .ToListAsync();

                    Console.WriteLine($"✓ Tech Corp contacts: {techCorpContacts.Count}");

                    if (techCorpContacts.Any())
                    {
                        foreach (var contact in techCorpContacts)
                        {
                            Console.WriteLine($"  - {contact.FirstName} {contact.LastName} - {contact.JobTitle}");
                        }
                    }

                    // Test 7: Get one specific contact
                    Console.WriteLine();
                    var specificContact = await context.Contacts
                        .FirstOrDefaultAsync(c => c.Email == "john.doe@example.com");

                    if (specificContact != null)
                    {
                        Console.WriteLine("✓ Found specific contact:");
                        Console.WriteLine($"  Name: {specificContact.FirstName} {specificContact.LastName}");
                        Console.WriteLine($"  Email: {specificContact.Email}");
                        Console.WriteLine($"  Phone: {specificContact.PhoneNumber}");
                        Console.WriteLine($"  Company: {specificContact.Company}");
                        Console.WriteLine($"  Job Title: {specificContact.JobTitle}");
                    }

                    // End of testing
                    Console.WriteLine("\n✓ All tests completed successfully!");
                    */
                }
            }
            catch (ArgumentException ex) 
            
            { Console.WriteLine(ex.Message); }

            catch (Exception ex)
            {
                Console.WriteLine("\n✗ Error occurred:");
                Console.WriteLine($"  Message: {ex.Message}");

            }
        }
    }
}

