using System;
using Microsoft.Data.Sqlite;
using Database.Dto;


namespace Team4
{
    public class Team4
    {
        public static List<BookDto> GetBooksByName(SqliteConnection conn, string name)
        {
            try
            {
                using (var command = conn.CreateCommand())
                {
                    command.CommandText = @"
                        SELECT book.ID, book.Name, book.YearOfRelease, book.Total,
                            author.ID, author.Name, author.Surname, author.DateOfBirth,
                            publisher.ID, publisher.Name, publisher.State
                        FROM Books book
                        LEFT JOIN Authors author ON book.AuthorID = author.ID
                        LEFT JOIN Publisher publisher ON book.PublisherID = publisher.ID
                        WHERE book.Name = @name;";
                    command.Parameters.AddWithValue("@name", name);

                    var books = new List<BookDto>();
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var book = new BookDto
                            {
                                Id = reader.GetInt32(0),
                                Name = reader.GetString(1),
                                YearOfRelease = reader.IsDBNull(2) ? 0 : reader.GetInt32(2),
                                Total = reader.IsDBNull(3) ? 0 : reader.GetInt32(3),
                                Author = new AuthorDto
                                {
                                    Id = reader.IsDBNull(4) ? 0 : reader.GetInt32(4),
                                    Name = reader.IsDBNull(5) ? "" : reader.GetString(5),
                                    Surname = reader.IsDBNull(6) ? "" : reader.GetString(6),
                                    DateOfBirth = reader.IsDBNull(7) ? DateTime.MinValue : reader.GetDateTime(7)
                                },
                                Publisher = new Publisher
                                {
                                    Id = reader.IsDBNull(8) ? 0 : reader.GetInt32(8),
                                    Name = reader.IsDBNull(9) ? "" : reader.GetString(9),
                                    State = reader.IsDBNull(10) ? "" : reader.GetString(10)
                                }
                            };
                            books.Add(book);
                        }
                    }
                    return books;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error in GetBooksByName: {ex.Message}");
                throw;
            }
        }
        public static List<BookDto> GetBooksByAuthor(SqliteConnection conn, AuthorDto author)
        {
            try
            {
                using (var command = conn.CreateCommand())
                {
                    command.CommandText = @"
                        SELECT book.ID, book.Name, book.YearOfRelease, book.Total,
                            publisher.ID, publisher.Name, publisher.State
                        FROM Books book
                        LEFT JOIN Publisher publisher ON book.PublisherID = publisher.ID
                        WHERE book.AuthorID = @id;";
                    command.Parameters.AddWithValue("@id", author.Id);

                    var books = new List<BookDto>();

                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            books.Add(new BookDto
                            {
                                Id = reader.GetInt32(0),
                                Name = reader.GetString(1),
                                YearOfRelease = reader.IsDBNull(2) ? 0 : reader.GetInt32(2),
                                Total = reader.IsDBNull(3) ? 0 : reader.GetInt32(3),
                                Author = author,
                                Publisher = new Publisher
                                {
                                    Id = reader.IsDBNull(4) ? 0 : reader.GetInt32(4),
                                    Name = reader.IsDBNull(5) ? "" : reader.GetString(5),
                                    State = reader.IsDBNull(6) ? "" : reader.GetString(6)
                                }
                            });
                        }
                    }
                    return books;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error in GetBooksByAuthor: {ex.Message}");
                throw;
            }
        }

        public static List<BookDto> GetBooksByAvailableBooks(SqliteConnection conn, int minStock = 1)
        {
            try
            {
                using (var command = conn.CreateCommand())
                {
                    command.CommandText = @"
                        SELECT book.ID, book.Name, book.YearOfRelease, book.Total
                        FROM Books book
                        WHERE book.Total >= @min;";
                    command.Parameters.AddWithValue("@min", minStock);

                    var books = new List<BookDto>();

                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            books.Add(new BookDto
                            {
                                Id = reader.GetInt32(0),
                                Name = reader.GetString(1),
                                YearOfRelease = reader.IsDBNull(2) ? 0 : reader.GetInt32(2),
                                Total = reader.IsDBNull(3) ? 0 : reader.GetInt32(3)
                            });
                        }
                    }
                    return books;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error in GetBooksByAvailableBooks: {ex.Message}");
                throw;
            }
        }

        public static List<BookDto> GetStolenBooks(SqliteConnection conn)
        {
            try
            {
                using (var command = conn.CreateCommand())
                {
                    command.CommandText = @"
                        SELECT book.ID, book.Name, book.YearOfRelease, book.Total
                        FROM Borrows borrow
                        INNER JOIN Books book ON borrow.BookID = book.ID
                        WHERE borrow.DateOfReturn IS NULL AND borrow.ReturnDue < DATE('now');";

                    var books = new List<BookDto>();
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            books.Add(new BookDto
                            {
                                Id = reader.GetInt32(0),
                                Name = reader.GetString(1),
                                YearOfRelease = reader.IsDBNull(2) ? 0 : reader.GetInt32(2),
                                Total = reader.IsDBNull(3) ? 0 : reader.GetInt32(3)
                            });
                        }
                    }
                    return books;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error in GetStolenBooks: {ex.Message}");
                throw;
            }
        }

        public static List<BookDto> GetStolenBooksByUser(SqliteConnection conn, UserDto user)
        {
            try
            {
                using (var command = conn.CreateCommand())
                {
                    command.CommandText = @"
                        SELECT book.ID, book.Name, book.YearOfRelease, book.Total
                        FROM Borrows borrow
                        INNER JOIN Books book ON borrow.BookID = book.ID
                        WHERE borrow.UserID = @uid AND borrow.DateOfReturn IS NULL AND borrow.ReturnDue < DATE('now');";
                    command.Parameters.AddWithValue("@uid", user.Id);

                    var books = new List<BookDto>();
                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            books.Add(new BookDto
                            {
                                Id = reader.GetInt32(0),
                                Name = reader.GetString(1),
                                YearOfRelease = reader.IsDBNull(2) ? 0 : reader.GetInt32(2),
                                Total = reader.IsDBNull(3) ? 0 : reader.GetInt32(3)
                            });
                        }
                    }
                    return books;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error in GetStolenBooksByUser: {ex.Message}");
                throw;
            }
        }

        public static AuthorDto GetAuthorById(SqliteConnection conn, int authorID)
        {
            try
            {
                using (var command = conn.CreateCommand())
                {
                    command.CommandText = @"
                        SELECT *
                        FROM Authors author
                        WHERE author.ID = @aid;";
                    command.Parameters.AddWithValue("@aid", authorID);

                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            return new AuthorDto
                            {
                                Id = reader.GetInt32(0),
                                Name = reader.GetString(1),
                                Surname = reader.GetString(2),
                                DateOfBirth = reader.GetDateTime(3)
                            };
                        }
                    }
                    return null;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error in GetAuthorById: {ex.Message}");
                throw;
            }
        }

        public static void GetBooksBy(SqliteConnection conn)
        {
            throw new NotImplementedException();
        }

        public static void GetBorrowLogBy(SqliteConnection conn)
        {
            throw new NotImplementedException();
        }
    }
}