using System;
using System.Linq;
using System.Net;
using System.Text;
using Windows.ApplicationModel.DataTransfer;

namespace Sonex.Client.Controls.DataGridView
{
    // Odpowiedzialnosc pliku: kopiowanie zaznaczenia do schowka jako tekst oraz HTML.
    public sealed partial class DataGridView
    {
        public void SelectToClipboard(bool withHeaders)
        {
            var snapshot = CreateExportSnapshot(new DataGridExportOptions
            {
                IncludeHeaders = withHeaders,
                RowScope = DataGridExportRowScope.SelectedRows,
                ColumnScope = DataGridExportColumnScope.SelectedColumns,
                FallbackToFilteredRowsWhenNoSelection = false,
                FallbackToVisibleColumnsWhenNoSelection = false
            });

            if (snapshot.Columns.Count == 0 || snapshot.RowIndexes.Count == 0)
                return;

            var package = new DataPackage();
            package.SetText(BuildClipboardText(snapshot, withHeaders));
            package.SetHtmlFormat(HtmlFormatHelper.CreateHtmlFormat(BuildClipboardHtml(snapshot, withHeaders)));
            package.RequestedOperation = DataPackageOperation.Copy;

            Clipboard.SetContent(package);
        }

        private string BuildClipboardText(ExportSnapshot snapshot, bool includeHeaders)
        {
            var sb = new StringBuilder(capacity: Math.Max(1024, snapshot.RowIndexes.Count * Math.Max(1, snapshot.Columns.Count) * 10));

            if (includeHeaders)
            {
                AppendDelimitedRow(
                    sb,
                    snapshot.Columns.Select(GetClipboardHeaderText),
                    "\t");
            }

            foreach (var rowIndex in snapshot.RowIndexes)
            {
                AppendDelimitedRow(
                    sb,
                    snapshot.Columns.Select(column => GetClipboardCellText(rowIndex, column)),
                    "\t");
            }

            return sb.ToString();
        }

        private string BuildClipboardHtml(ExportSnapshot snapshot, bool includeHeaders)
        {
            var sb = new StringBuilder(capacity: Math.Max(2048, snapshot.RowIndexes.Count * Math.Max(1, snapshot.Columns.Count) * 24));
            sb.Append("<table style=\"border-collapse:collapse;font-family:'Segoe UI',Arial,sans-serif;font-size:12px;color:#000000;background:#ffffff;\">");

            if (includeHeaders)
            {
                sb.Append("<thead><tr>");
                foreach (var column in snapshot.Columns)
                {
                    sb.Append("<th style=\"")
                        .Append(GetClipboardHeaderStyle())
                        .Append("\">")
                        .Append(WebUtility.HtmlEncode(GetClipboardHeaderText(column)))
                        .Append("</th>");
                }
                sb.Append("</tr></thead>");
            }

            sb.Append("<tbody>");
            foreach (var rowIndex in snapshot.RowIndexes)
            {
                sb.Append("<tr>");
                foreach (var column in snapshot.Columns)
                {
                    sb.Append("<td style=\"")
                        .Append(GetClipboardCellStyle(column))
                        .Append("\">")
                        .Append(WebUtility.HtmlEncode(GetClipboardCellText(rowIndex, column)))
                        .Append("</td>");
                }
                sb.Append("</tr>");
            }
            sb.Append("</tbody></table>");

            return sb.ToString();
        }

        private static string GetClipboardHeaderText(Column column)
        {
            return NormalizeCell(string.IsNullOrWhiteSpace(column.Title) ? column.Name : column.Title);
        }

        private string GetClipboardCellText(int rowIndex, Column column)
        {
            return NormalizeCell(GetExportValue(rowIndex, column));
        }

        private static string GetClipboardHeaderStyle()
        {
            return "border:1px solid #E3E3E3;padding:8px 10px;background:#F9F9F9;color:#626262;font-weight:600;text-align:left;white-space:nowrap;";
        }

        private static string GetClipboardCellStyle(Column column)
        {
            var style = new StringBuilder("border:1px solid #E3E3E3;padding:8px 10px;background:#FFFFFF;white-space:nowrap;");

            switch (column.TextFormat?.HorizontalAlignment)
            {
                case Microsoft.Graphics.Canvas.Text.CanvasHorizontalAlignment.Right:
                    style.Append("text-align:right;");
                    break;
                case Microsoft.Graphics.Canvas.Text.CanvasHorizontalAlignment.Center:
                    style.Append("text-align:center;");
                    break;
                default:
                    style.Append("text-align:left;");
                    break;
            }

            return style.ToString();
        }

        private static string NormalizeCell(string? s)
        {
            if (string.IsNullOrEmpty(s)) return "";

            return s.Replace("\t", " ")
                    .Replace("\r", " ")
                    .Replace("\n", " ");
        }

    }
}
