using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Электронная_Фармация.Properties;

namespace Электронная_Фармация.Classes
{
    public class DataSender
    {
        private const string BuyerOrdersEndpoint = "/api/buyer/orders";

        private string _baseUrl;
        private string _token;

        public async Task Main()
        {
            _token = Settings.Default.stringToken;
            _baseUrl = AppConfig.ApiBaseUrl;

            if (string.IsNullOrWhiteSpace(_token))
            {
                ToastNotification.ShowError("Не найден токен авторизации.");
                return;
            }

            if (string.IsNullOrWhiteSpace(AppConfig.LocationId))
            {
                ToastNotification.ShowCustom(
                    "Не указан location_id. Заполните его в окне авторизации/настроек.",
                    Color.DarkOrange,
                    Color.White);
                return;
            }

            var orders = FetchDataFromSql(null);
            if (orders.Count == 0)
            {
                ToastNotification.ShowCustom("Нет новых заказов для отправки.", Color.DarkOrange, Color.White);
                return;
            }

            int successCount = 0;
            int failCount = 0;

            foreach (var order in orders)
            {
                bool ok = await SendOrderAsync(order);
                if (ok)
                {
                    successCount++;
                }
                else
                {
                    failCount++;
                }
            }

            if (successCount > 0 && failCount == 0)
            {
                ToastNotification.ShowSuccess($"Отправлено заказов: {successCount}");
            }
            else if (successCount > 0)
            {
                ToastNotification.ShowCustom(
                    $"Отправлено: {successCount}, с ошибкой: {failCount}",
                    Color.DarkOrange,
                    Color.White);
            }
        }

        /// <summary>
        /// Sends a single local order by Id_Order (must be in state НОВЫЙ).
        /// </summary>
        public async Task<bool> SendSingleOrderAsync(string localOrderId)
        {
            _token = Settings.Default.stringToken;
            _baseUrl = AppConfig.ApiBaseUrl;

            if (string.IsNullOrWhiteSpace(_token))
            {
                ToastNotification.ShowError("Не найден токен авторизации.");
                return false;
            }

            if (string.IsNullOrWhiteSpace(AppConfig.LocationId))
            {
                ToastNotification.ShowCustom(
                    "Не указан location_id. Заполните его в окне авторизации/настроек.",
                    Color.DarkOrange,
                    Color.White);
                return false;
            }

            var orders = FetchDataFromSql(localOrderId);
            if (orders.Count == 0)
            {
                ToastNotification.ShowCustom("Заказ не найден или уже отправлен.", Color.DarkOrange, Color.White);
                return false;
            }

            bool ok = await SendOrderAsync(orders[0]);
            if (ok)
            {
                ToastNotification.ShowSuccess("Заказ отправлен");
            }

            return ok;
        }

        public List<BuyerOrderRequest> FetchDataFromSql(string onlyOrderId)
        {
            var orders = new Dictionary<string, BuyerOrderRequest>();
            string locationId = AppConfig.LocationId;

            using (var connection = new SQLiteConnection(AppConfig.SqliteConnectionString))
            {
                connection.Open();
                string query = @"
SELECT
    Orders.Id_Order,
    OrderItems.supplier_price_id,
    OrderItems.Zakaz,
    Orders.Comment
FROM Orders
INNER JOIN OrderItems ON OrderItems.Id_Order = Orders.Id_Order
WHERE Orders.OrderState = 'НОВЫЙ'
";
                if (!string.IsNullOrWhiteSpace(onlyOrderId))
                {
                    query += " AND Orders.Id_Order = @orderId";
                }

                query += " ORDER BY Orders.Id_Order";

                using (var command = new SQLiteCommand(query, connection))
                {
                    if (!string.IsNullOrWhiteSpace(onlyOrderId))
                    {
                        command.Parameters.AddWithValue("@orderId", onlyOrderId);
                    }

                    using (var reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            string orderId = reader["Id_Order"].ToString().Trim();
                            string supplierPriceId = reader["supplier_price_id"].ToString().Trim();
                            decimal qty = ReadDecimal(reader["Zakaz"]);

                            if (string.IsNullOrWhiteSpace(supplierPriceId))
                            {
                                throw new InvalidOperationException($"В заказе {orderId} есть позиция без supplier_price_id.");
                            }

                            if (qty <= 0)
                            {
                                throw new InvalidOperationException($"В заказе {orderId} количество должно быть больше нуля.");
                            }

                            if (!orders.TryGetValue(orderId, out BuyerOrderRequest order))
                            {
                                order = new BuyerOrderRequest
                                {
                                    LocalOrderId = orderId,
                                    LocationId = locationId,
                                    Comment = reader["Comment"] == DBNull.Value ? null : reader["Comment"].ToString()
                                };
                                orders.Add(orderId, order);
                            }

                            order.Items.Add(new BuyerOrderItem
                            {
                                SupplierPriceId = supplierPriceId,
                                Qty = qty
                            });
                        }
                    }
                }
            }

            return orders.Values.ToList();
        }

        private async Task<bool> SendOrderAsync(BuyerOrderRequest order)
        {
            var options = new JsonSerializerOptions
            {
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
            };
            string json = JsonSerializer.Serialize(order, options);

            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(_baseUrl);
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token);

                var content = new StringContent(json, Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.PostAsync(BuyerOrdersEndpoint, content);
                string responseString = await response.Content.ReadAsStringAsync();

                if (!response.IsSuccessStatusCode)
                {
                    ToastNotification.ShowError(
                        $"Ошибка отправки заказа {order.LocalOrderId}: {(int)response.StatusCode} {response.ReasonPhrase}\n{responseString}");
                    return false;
                }

                MarkOrderSent(order.LocalOrderId);
                return true;
            }
        }

        private static void MarkOrderSent(string localOrderId)
        {
            if (string.IsNullOrWhiteSpace(localOrderId))
            {
                return;
            }

            using (var con = new SQLiteConnection(AppConfig.SqliteConnectionString))
            {
                con.Open();
                using (var cmd = new SQLiteCommand(
                    "UPDATE [Orders] SET [OrderState] = 'ОТПРАВЛЕН' WHERE [Id_Order] = @id AND [OrderState] = 'НОВЫЙ'",
                    con))
                {
                    cmd.Parameters.AddWithValue("@id", localOrderId);
                    cmd.ExecuteNonQuery();
                }
            }
        }

        private static decimal ReadDecimal(object value)
        {
            if (value == null || value == DBNull.Value)
            {
                return 0;
            }

            string text = value.ToString();
            if (decimal.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out decimal invariantValue))
            {
                return invariantValue;
            }

            if (decimal.TryParse(text, NumberStyles.Number, CultureInfo.CurrentCulture, out decimal currentCultureValue))
            {
                return currentCultureValue;
            }

            throw new InvalidOperationException($"Некорректное количество: {text}");
        }
    }

    public class BuyerOrderRequest
    {
        [JsonIgnore]
        public string LocalOrderId { get; set; }

        [JsonPropertyName("location_id")]
        public string LocationId { get; set; }

        [JsonPropertyName("comment")]
        public string Comment { get; set; }

        [JsonPropertyName("items")]
        public List<BuyerOrderItem> Items { get; set; } = new List<BuyerOrderItem>();
    }

    public class BuyerOrderItem
    {
        [JsonPropertyName("supplier_price_id")]
        public string SupplierPriceId { get; set; }

        [JsonPropertyName("qty")]
        public decimal Qty { get; set; }
    }
}
