using System;
using System.Globalization;
using System.Linq;

namespace Sonex.Client.Controls.DataGridView
{
    // Odpowiedzialnosc pliku: konwersja wartosci komorki do bezpiecznego formatu eksportowego.
    public sealed partial class DataGridView
    {
        private static readonly CultureInfo ExportCulture = CultureInfo.CurrentCulture;

        // klonujemy NumberFormat, żeby wyłączyć grupowanie (tysiące)
        private static readonly NumberFormatInfo ExportNumberFormat = CreateExportNumberFormat();

        private static NumberFormatInfo CreateExportNumberFormat()
        {
            var nfi = (NumberFormatInfo)ExportCulture.NumberFormat.Clone();
            nfi.NumberGroupSeparator = ""; // brak 1,000 / 1.000
            nfi.NumberGroupSizes = new[] { 0 };
            return nfi;
        }

        public string? GetExportValue(int rowIndex, Column column)
        {
            if (_ItemsSourceFiltred == null) return null;
            if (rowIndex < 0 || rowIndex >= _ItemsSourceFiltred.Count) return null;

            if (column?.PropertyInfo == null) return null;

            var item = _ItemsSourceFiltred[rowIndex];
            if (item == null) return null;

            var value = column.PropertyInfo.GetValue(item);
            if (value == null) return null;

            var t = Nullable.GetUnderlyingType(column.PropertyInfo.PropertyType)
                    ?? column.PropertyInfo.PropertyType;

            // 1) całkowite: kultura systemu, bez grupowania
            if (t == typeof(int) || t == typeof(uint) ||
                t == typeof(long) || t == typeof(ulong) ||
                t == typeof(short) || t == typeof(ushort) ||
                t == typeof(byte) || t == typeof(sbyte))
            {
                return Convert.ToString(value, ExportCulture);
            }

            // 2) zmiennoprzecinkowe: separator . lub , z CurrentCulture, bez grupowania
            if (t == typeof(float))
                return ((float)value).ToString("0.################", ExportNumberFormat);

            if (t == typeof(double))
                return ((double)value).ToString("0.################", ExportNumberFormat);

            if (t == typeof(decimal))
                return ((decimal)value).ToString("0.################", ExportNumberFormat);

            // 3) daty/czas: zostawiam ISO (najpewniejsze dla Excela)
            if (t == typeof(DateTime))
                return ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);

            if (t == typeof(DateOnly))
                return ((DateOnly)value).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

            if (t == typeof(TimeOnly))
                return ((TimeOnly)value).ToString("HH:mm:ss", CultureInfo.InvariantCulture);

            if (t == typeof(TimeSpan))
                return ((TimeSpan)value).ToString(@"d\.hh\:mm\:ss", CultureInfo.InvariantCulture);

            // 4) bool: excelowe TRUE/FALSE
            if (t == typeof(bool))
                return ((bool)value) ? "TRUE" : "FALSE";

            // 5) Guid/bytes
            if (t == typeof(Guid))
                return ((Guid)value).ToString("D");

            if (t == typeof(byte[]))
                return Convert.ToHexString((byte[])value);

            // 6) string / reszta
            var text = NormalizeTsvCell(value.ToString() ?? "");

            // 7) Wiodące 0 przy samych cyfrach ="003456"
            //if (ShouldForceExcelText(text))
            //    return ForceExcelText(text);

            return text;
        }

        private static string NormalizeTsvCell(string s)
            => s.Replace("\t", " ")
                .Replace("\r", " ")
                .Replace("\n", " ")
                .Trim();

        private static bool ShouldForceExcelText(string s)
        {
            if (string.IsNullOrEmpty(s)) return false;

            // wiodące zera i same cyfry => "001234"
            if (s.Length >= 2 && s[0] == '0' && s.All(char.IsDigit))
                return true;

            // >15 cyfr => Excel traci precyzję
            if (s.Length > 15 && s.All(char.IsDigit))
                return true;

            return false;
        }

        private static string ForceExcelText(string s)
        {
            s = s.Replace("\"", "\"\"");
            return $"=\"{s}\"";
        }
    }
}