using AIProofread.Model;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
using UtilLib;
using System;
using log4net;

namespace AIProofread.core
{
    public class CorrectResultExportor
    {

        public ILog Logger = LogHelper.GetLogger(typeof(CorrectResultExportor));
        // 设置表头
        private static readonly string[] HeaderCols =
        {
            "序号","页","行","详细信息","异常", "建议","处理状态"
        };

        private static CorrectResultExportor exportor = new CorrectResultExportor();

        private HexBinaryValue primaryColor = new HexBinaryValue("FFD6AA69");
        private HexBinaryValue whiteColor = new HexBinaryValue("FFFFFFFF");
        private HexBinaryValue blackColor = new HexBinaryValue("FF000000");

        private CorrectResultExportor()
        {
        }
        public static CorrectResultExportor GetInstance()
        {
            return exportor;
        }

        private Stylesheet CreateStyleSheet()
        {
            // 字体样式（默认和微软雅黑）
            Fonts fonts = new Fonts(
                new Font( // 默认字体
                    new FontName() { Val = "宋体" },
                    new FontSize() { Val = 11 }
                ),
                new Font( // 微软雅黑字体
                    new FontName() { Val = "黑体" },
                    new RunFont() { Val = "黑体" },
                    new FontSize() { Val = 11 }
                ),
                new Font( // 首行表头
                    new FontName() { Val = "黑体" },
                    new RunFont() { Val = "黑体" },
                    new FontSize() { Val = 11 },
                    new Color() { Rgb = primaryColor } // 字体颜色
                ),
                new Font( // 首行表头
                    new FontName() { Val = "宋体" },
                    new RunFont() { Val = "宋体" },
                    new FontSize() { Val = 11 }
                )
            );

            // 背景填充（黑色/金色）
            Fills fills = new Fills(
                new Fill(new PatternFill() { PatternType = PatternValues.None }),
                new Fill(new PatternFill()
                {
                    PatternType = PatternValues.Solid,
                    ForegroundColor = new ForegroundColor() { Rgb = blackColor }
                }),
                new Fill(new PatternFill()
                {
                    PatternType = PatternValues.Solid,
                    ForegroundColor = new ForegroundColor() { Rgb = blackColor }
                })
            );

            // 边框样式
            Borders borders = new Borders(
                new Border(), // 默认无边框
                new Border(
                    new LeftBorder() { Style = BorderStyleValues.Thin, Color = new Color() { Rgb = blackColor } },
                    new RightBorder() { Style = BorderStyleValues.Thin, Color = new Color() { Rgb = blackColor } },
                    new TopBorder() { Style = BorderStyleValues.Thin, Color = new Color() { Rgb = blackColor } },
                    new BottomBorder() { Style = BorderStyleValues.Thin, Color = new Color() { Rgb = blackColor } },
                    new DiagonalBorder()
                )
            );

            // 单元格样式
            CellFormats cellFormats = new CellFormats(
                new CellFormat() // 默认
                {
                    ApplyAlignment = true,
                    Alignment = new Alignment()
                    {
                        Horizontal = HorizontalAlignmentValues.Left,
                        Vertical = VerticalAlignmentValues.Center,
                        WrapText = true
                    }
                },
                new CellFormat() // 首行
                {
                    FontId = 2, // 使用黑体字体
                    FillId = 2, // 使用黑色背景

                    ApplyFont = true,
                    ApplyFill = true,
                    ApplyAlignment = true,
                    Alignment = new Alignment()
                    {
                        Horizontal = HorizontalAlignmentValues.Center,
                        Vertical = VerticalAlignmentValues.Center,
                        WrapText = true
                    }
                },
                new CellFormat() // 单纯的黑体
                {
                    FontId = 1,
                    ApplyFont = true,
                    ApplyAlignment = true,
                    Alignment = new Alignment()
                    {
                        Horizontal = HorizontalAlignmentValues.Center,
                        Vertical = VerticalAlignmentValues.Center,
                        WrapText = true
                    }
                },
                new CellFormat() // 单纯的黑体
                {
                    FontId = 3,
                    ApplyFont = true,
                    Alignment = new Alignment()
                    {
                        Horizontal = HorizontalAlignmentValues.Left,
                        Vertical = VerticalAlignmentValues.Center,
                        WrapText = true
                    }
                }
            );

            return new Stylesheet(fonts, fills, borders, cellFormats);
        }
        /// <summary>
        /// 使用Excel COM导出
        /// </summary>
        /// <param name="fileName"></param>
        public void ExportResult(string fileName)
        {
            // 创建计时器,用于计算运行时间
            var stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start();
            // 获取要导出的数据
            var exportDataItems = ExportDataItem.GetExportData(Globals.ThisAddIn.ActiveDocument.marks);
            // 创建Excel对象
            using (SpreadsheetDocument document = SpreadsheetDocument.Create(fileName, SpreadsheetDocumentType.Workbook))
            {
                #region 创建 Workbook 和 Worksheet
                WorkbookPart workbookPart = document.AddWorkbookPart();
                // 设置样式
                var stylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
                stylesPart.Stylesheet = CreateStyleSheet();
                stylesPart.Stylesheet.Save();

                // 创建工作簿
                workbookPart.Workbook = new Workbook();

                WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
                var worksheet = new Worksheet();
                // 冻结首行
                worksheet.Append(new SheetViews(
                    new SheetView()
                    {
                        WorkbookViewId = 0,
                        Pane = new Pane()
                        {
                            VerticalSplit = 1,
                            TopLeftCell = "A2",
                            ActivePane = PaneValues.BottomLeft,
                            State = PaneStateValues.Frozen
                        }
                    }
                ));
                worksheetPart.Worksheet = worksheet;
                // 创建 
                Sheets sheets = document.WorkbookPart.Workbook.AppendChild(new Sheets());

                // 美化sheet
                StyleSheet(worksheet); // column 必须在sheet data 之前
                worksheet.Append(new SheetData());
                Sheet sheet = new Sheet()
                {
                    Id = document.WorkbookPart.GetIdOfPart(worksheetPart),
                    SheetId = 1,
                    Name = "Sheet1"
                };
                sheets.Append(sheet);
                #endregion
                // 获取 SheetData
                SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
                // 创建表头
                CreateHeader(sheetData);
                int rowIndex = 1;
                foreach (var item in exportDataItems)
                {
                    // 创建行
                    try
                    {
                        CreateRow(sheetData, item, ref rowIndex);
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("导出勘误表异常：" + ex.Message, ex);
                    }
                }
                // 筛选
                worksheetPart.Worksheet.Append(new AutoFilter { Reference = "A1:G1" });
                //sheet.Append(new AutoFilter() { Reference = "A1:G1"});
            }

            stopwatch.Stop();
            Logger.Info("导出勘误表" + fileName + "完成,运行时间：" + stopwatch.Elapsed.TotalMilliseconds + "毫秒");

        }

        private void StyleSheet(Worksheet worksheet)
        {
            // 设置列宽
            Columns columns = new Columns();
            SetColumnWidth(1, 0, columns); // 隐藏第一列
            SetColumnWidth(2, 3, 6, columns);
            SetColumnWidth(4, 80, columns);
            SetColumnWidth(5, 6, 20, columns);
            SetColumnWidth(7, 10, columns);
            worksheet.Append(columns);

        }
        private void SetColumnWidth(uint colIndex, int width, Columns columns)
        {
            SetColumnWidth(colIndex, colIndex, width, columns);
        }
        private void SetColumnWidth(uint startColIndex, uint endColIndex, int width, Columns columns)
        {
            columns.Append(
                new Column()
                {
                    Min = startColIndex, // 从第1列开始
                    Max = endColIndex, // 到第3列结束
                    Width = width, // 宽度值（一般 8.43 为默认）
                    CustomWidth = true,
                    Hidden = width <= 0,
                }
            );
        }

        private void CreateHeader(SheetData sheetData)
        {
            // 创建表头行
            Row headerRow = new Row() { Height = 40, CustomHeight = true };
            foreach (var header in HeaderCols)
            {
                headerRow.AppendChild(new Cell()
                {
                    DataType = CellValues.String,
                    StyleIndex = 1,  // 设置背景为黑色，字体为金色
                    CellValue = new CellValue(header)
                });
            }
            sheetData.AppendChild(headerRow);
        }

        private void CreateRow(SheetData sheetData, ExportDataItem item, ref int rowIndex)
        {
            var it = item.Item;

            Row row = new Row();

            // 写入数据
            // 1. 序号
            CreateNormalCell(rowIndex, row);
            // 2. 页码
            CreateNormalCell(item.PageNumber, row);
            // 3. 行号
            CreateNormalCell(item.LineNumber, row);
            // 4. 引用原文(详细信息)
            CreateOriginSentenceCell(row, item);
            // 5. 异常
            CreateNormalCell(it.Origin, row, 3);
            // 6. 建议
            CreateCorrectSuggestCell(row, item);
            // 7. 处理状态
            CreateNormalCell(StatusText(it.IsAccept), row, 2);

            sheetData.AppendChild(row);
            rowIndex++;
        }

        private string StatusText(int status)
        {
            if (status == AcceptStatus.Accept) return "已采纳";
            else if (status == AcceptStatus.Review) return "已复核";
            else if (status == AcceptStatus.Ignore) return "已忽略";

            return "未处理";
        }

        /// <summary>
        /// 创建普通单元格
        /// </summary>
        /// <param name="value"></param>
        /// <param name="row"></param>
        /// <param name="styleIndex">样式索引id,从0开始</param>
        private void CreateNormalCell(object value, Row row, uint styleIndex)
        {
            row.AppendChild(new Cell()
            {
                DataType = CellValues.String,
                StyleIndex = styleIndex,
                CellValue = new CellValue(value == null ? string.Empty : value.ToString()) { Space = SpaceProcessingModeValues.Preserve }
            });
        }
        private void CreateNormalCell(object value, Row row)
        {
            row.AppendChild(new Cell()
            {
                DataType = CellValues.String,
                CellValue = new CellValue(value == null ? string.Empty : value.ToString()) { Space = SpaceProcessingModeValues.Preserve }
            });
        }

        /// <summary>
        /// 创建引用原文(详细信息)单元格
        /// </summary>
        /// <param name="row"></param>
        /// <param name="item"></param>
        private void CreateOriginSentenceCell(Row row, ExportDataItem item)
        {
            var it = item.Item;
            string originSentence = item.OriginSentence.TrimEnd();
            //var startIndex = it.Tag == "i" || it.Start < originSentence.Length - 1 ? it.Start : originSentence.IndexOf(it.Origin);
            var cell = new Cell()
            {
                DataType = CellValues.InlineString,
                StyleIndex = 3
            };

            var beforeText = it.Start == 0 ? null : originSentence.Substring(0, it.Start);
            var richTextLength = it.Origin.Length; // it.Tag == "i" ? 1 : it.Text.Length
            var richText = originSentence.Substring(it.Start, richTextLength);
            var afterText = it.Start >= originSentence.Length ? null : originSentence.Substring(it.Start + richTextLength);

            var inlineString = new InlineString();
            AppendRichTextToCell(beforeText, inlineString);
            AppendRichTextToCell(richText, inlineString, "FFFF0000");
            AppendRichTextToCell(afterText, inlineString);
            cell.InlineString = inlineString;
            row.AppendChild(cell);
        }

        private void CreateCorrectSuggestCell(Row row, ExportDataItem item)
        {
            var it = item.Item;
            var cell = new Cell()
            {
                DataType = CellValues.InlineString,
                StyleIndex = 3
            };
            var inlineString = new InlineString();

            var suggest = it.Text;
            if (it.Tag == "r")
            {
                string tag = "";
                if (it.Type == "blacklist")
                {
                    tag = "黑名单";
                }
                else
                {
                    // 易错词 标点 不标识
                    if (it.Type == "confusion" || it.Type == "model" || it.Type == "other" || it.Type == "punctuation")
                    {
                        //row.CreateCell(5).SetCellValue(suggest);
                    }
                    else if (!string.IsNullOrEmpty(it.Type) && ExportConfig.ErrorTypeMap.ContainsKey(it.Type.ToLower()))
                    {

                        tag = $"【提示】{ExportConfig.ErrorTypeMap[it.Type.ToLower()]}";
                    }
                    else if (!string.IsNullOrEmpty(it.Addition) && it.Addition.Trim().Length > 0 && it.Addition != "提示")
                    {
                        tag = $"【提示】{it.Addition}";
                    }
                }


                if (!string.IsNullOrEmpty(tag))
                {
                    AppendNormalTextToCell(suggest + " ", inlineString);
                    AppendRichTextToCell(tag, inlineString, "000000", "黑体");
                }
                else
                {
                    AppendNormalTextToCell(suggest, inlineString);
                }

            }
            else
            {
                string tag = "";
                if (it.Type == "incorrect_expression")
                {
                    tag = "表述有误";
                }
                else if (it.Type == "sensitive")
                {
                    tag = "敏感词";
                }
                else if (it.Type == "blacklist" || it.Type == "blacklist_mask")
                {
                    tag = "黑名单";
                }
                else if (it.Type == "fallen_officers")
                {
                    tag = "疑似落马官员";
                }
                else if (it.Tag == "i")
                {
                    AppendNormalTextToCell(it.Text, inlineString);
                    tag = " 新增";
                }
                else if (it.Tag == "d")
                {
                    tag = "删除";
                }

                if (tag.Length > 0)
                {
                    AppendRichTextToCell(tag, inlineString, "000000", "黑体");
                }
                else
                {
                    AppendNormalTextToCell(suggest, inlineString);
                }
            }
            cell.InlineString = inlineString;
            row.AppendChild(cell);
        }

        private void AppendNormalTextToCell(string text, InlineString inlineString, string color = "FF000000", string fontName = "宋体")
        {
            if (string.IsNullOrEmpty(text)) return;
            var props = new RunProperties(
                new FontSize() { Val = 11 }
                );
            if (color != "FF000000") props.Append(new Color() { Rgb = new HexBinaryValue(color) });
            if (fontName != "宋体") props.Append(new RunFont() { Val = fontName });
            var run = new Run(
                props,
                new Text(text) { Space = SpaceProcessingModeValues.Preserve }
            );
            inlineString.Append(run);

        }

        private void AppendRichTextToCell(string text, InlineString inlineString, string color = "FF000000", string fontName = "宋体")
        {
            if (string.IsNullOrEmpty(text)) return;
            var props = new RunProperties(
                new FontSize() { Val = 11 }
            );
            if (color != "000000") props.Append(new Color() { Rgb = new HexBinaryValue(color) });
            if (fontName != "宋体") props.Append(new RunFont() { Val = fontName });
            var run = new Run(props, new Text(text) { Space = SpaceProcessingModeValues.Preserve });
            inlineString.Append(run);
        }
    }
}
