using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using MySql.Data.MySqlClient;
using Newtonsoft.Json;

namespace Server
{
    // there should be a better way to deal with data comming from sql
    public class Log
    {
        public object? f_name { get; set; }
        public object? l_name { get; set; }
        public object? mail { get; set; }
        public object? name { get; set; }
        public object? time { get; set; }
        public object? date { get; set; }
        public object? user { get; set; }
    }

    public class Getall : Route
    {
        public static void HandleRequest(HttpListenerRequest request, HttpListenerResponse response)
        {
            try
            {
                // prepare SQL query
                MySqlCommand cmd = new MySqlCommand();
                // get url params
                var queryString = request.QueryString;
                string? from = queryString["from"];
                string? to = queryString["to"];
                string? sortby = queryString["sortby"];
                string? offset = queryString["offset"];
                string? order = queryString["order"];
                order = order == "true" ? "ASC" : "DESC";
                // this shenanigan is needed to remove the "" around group by
                string mainQuery = @"SELECT u.f_name,u.l_name,u.mail,p.name,t.time,t.date,t.user 
                                     FROM Timelog t 
                                     INNER JOIN Project p ON p.id=t.project 
                                     INNER JOIN User u ON u.id=t.user ";
                string offsetQuery = " LIMIT 10 OFFSET " + offset + ";";
                // depending on the incoming parameters construct a Query
                if (!string.IsNullOrEmpty(to) && !string.IsNullOrEmpty(from))
                {
                    Regex regex = new Regex(@"^\d{4}-\d{2}-\d{2}$");
                    if (!regex.IsMatch(to) || !regex.IsMatch(from))
                    {
                        throw new Exception("Incorrect date format");
                    }
                    string whereQuery = " WHERE t.date BETWEEN @from AND @to ";
                    mainQuery = mainQuery + whereQuery;
                }
                if (!string.IsNullOrEmpty(sortby))
                {
                    List<string> validSorting = new List<string> { "f_name", "l_name", "mail", "time", "date", "user", };
                    if (!validSorting.Contains(sortby))
                    {
                        throw new Exception("Incorrect sorting value");
                    }
                    string orderQuery = " ORDER BY " + sortby + " " + order;
                    mainQuery = mainQuery + orderQuery;
                }
                if (!int.TryParse(offset, out int myInt) || myInt < 0)
                    throw new Exception("Incorect offset");
                // add the final line to the query
                cmd.CommandText = mainQuery + offsetQuery;
                // those don't produce error if they don't find their variables
                cmd.Parameters.AddWithValue("@from", from);
                cmd.Parameters.AddWithValue("@to", to);

                using (MySqlConnection conn = new MySqlConnection(connectionString))
                {
                    conn.Open();
                    cmd.Connection = conn;
                    // execute query and read results
                    MySqlDataReader reader = cmd.ExecuteReader();

                    List<Log> entries = new List<Log>();
                    while (reader.Read())
                    {
                        entries.Add(new Log
                        {
                            f_name = reader["f_name"],
                            l_name = reader["l_name"],
                            user = reader["user"],
                            date = reader["date"],
                            name = reader["name"],
                            time = reader["time"],
                            mail = reader["mail"],
                        });
                    }
                    // serialize JSON
                    string jsonResponse = JsonConvert.SerializeObject(entries);
                    SendSuccess(response, jsonResponse);
                }
            }
            catch (Exception ex)
            {
                SendError(response, ex);
            }
        }
    }
}
