using Model;
using StandardLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;

namespace YangjieTester
{
    public class BatchReport
    {
        public static string GenerateBatchReport(Batch batch)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"批次开始时间：{batch.StartTime}");
            
            if (!batch.Finished)
                sb.AppendLine($"批次当前时间：{DateTime.Now}");
            else
                sb.AppendLine($"批次结束时间：{batch.EndTime - batch.StartTime}");

            if (!batch.Finished)
                sb.AppendLine($"开批次时间：{DateTime.Now - batch.StartTime}");
            else
                sb.AppendLine($"开批次时间：{batch.EndTime - batch.StartTime}");

            sb.AppendLine($"\t配方：{batch.RecipeName}");
            sb.AppendLine($"\t批次：{batch.BatchID}");
            sb.AppendLine($"\tMTBA：{PlcDataConvert.FormatDWordSpanToDHMS(batch.MTBA)}");
            sb.AppendLine($"\tMTBF：{PlcDataConvert.FormatDWordSpanToDHMS(batch.MTBF)}");
            sb.AppendLine($"\tMTTR：{PlcDataConvert.FormatDWordSpanToDHMS(batch.MTTR)}");
            sb.AppendLine($"\t正常生产时间：{PlcDataConvert.FormatDWordSpanToDHMS(batch.NormalWorkingTimeSpan)}");
            sb.AppendLine($"\tMUBA：{batch.MUBA}");
            sb.AppendLine($"\tUPH：{batch.UPH:f2}");
            sb.AppendLine($"\t报警次数：{batch.AlarmCount}");
            sb.AppendLine($"\t故障时间：{batch.ErrorTimeSpan}");
            sb.AppendLine($"\t设备使用率：{batch.WorkingTimeRate:f1}%");
            sb.AppendLine($"批次总数量：{batch.TotalNumOfBatch}");
            sb.AppendLine($"编带总数量：{batch.TapedNumOfBatch}");

            sb.AppendLine("-------------------------------------------------");

            /******************************测试结果信息**********************************************/
            var testResults = PropertyFinder.FindPropertiesOfType<TestResult>(batch);
            List<string[]> rows = new List<string[]>();
            string[] row = new string[] { "项目", "状态", "良率", "时间", "良品", "不良品", "总数量" };
            rows.Add(row);
            foreach (var tr in testResults)
            {
                row = new string[] { tr.Name, tr.TestEnable ? "开" : "关", tr.OkRate.ToString("f2") + "%", tr.Time.ToString(), tr.OkNum.ToString(), tr.NgNum.ToString(), tr.TotalNum.ToString() };
                rows.Add(row);
            }
            sb.AppendLine(FormatTableForMonospace(rows, 12));

            sb.AppendLine("-------------------------------------------------");

            /******************************Bin盒信息**********************************************/

            rows = new List<string[]>();
            row = new string[] { "项目", "数量", "上限", "总数量" };
            rows.Add(row);
            var binBoxNum = PropertyFinder.FindPropertiesOfType<BinBoxNum>(batch);
            foreach (var bbn in binBoxNum)
            {
                row = new string[] { bbn.Name, bbn.Count.ToString(), bbn.UpLimit.ToString(), bbn.TotalCount.ToString() };
                rows.Add(row);
            }
            sb.AppendLine(FormatTableForMonospace(rows, 12));

            sb.AppendLine("------------------报警信息---------------------------");


            DateTime endTime;

            if (!batch.Finished)
                endTime = DateTime.Now;
            else
                endTime = batch.EndTime;

            var alarmList = AlarmService.GetAlarmsByTimeRange(batch.StartTime, endTime)
                            .Select((item, index) => { item.RowNumber = index + 1; return item; })
                            .ToList();

            //alarmList.Add( new AlarmDisplay(){ Timestamp = DateTime.Now.AddDays(0), AlarmType = "Error", Username = "op1", AlarmMessage = "Alarm01" });
            //alarmList.Add(new AlarmDisplay() { Timestamp = DateTime.Now.AddDays(2), AlarmType = "Error", Username = "op1", AlarmMessage = "Alarm02" });
            //alarmList.Add(new AlarmDisplay() { Timestamp = DateTime.Now.AddDays(2.1), AlarmType = "Error", Username = "op1", AlarmMessage = "Alarm03" });

            //alarmList.Add(new AlarmDisplay() { Timestamp = DateTime.Now.AddDays(1), AlarmType = "Cleared", Username = "op1", AlarmMessage = "Alarm01" });
            //alarmList.Add(new AlarmDisplay() { Timestamp = DateTime.Now.AddDays(3), AlarmType = "Cleared", Username = "op1", AlarmMessage = "Alarm02" });

            
            var palms = PairedAlarm.PairAlarms(alarmList);
            sb.AppendLine($"报警总数：{palms.Count}");
            sb.AppendLine("发生时间，结束时间，经过时间，停机类别，报警内容");
            foreach (var item in palms)
            {
                sb.AppendLine($"{item.StartTime}，{item.EndTime}，{item.EndTime - item.StartTime}，{item.Type}，{item.AlarmMessage}");
            }

            return sb.ToString();
        }
        static int GetDisplayWidth(string s)
        {
            if (string.IsNullOrEmpty(s)) return 0;
            int width = 0;
            foreach (char c in s)
            {
                // 常见中文字符范围（包括中文标点）
                if (char.IsLetterOrDigit(c) || char.IsPunctuation(c) || char.IsSymbol(c))
                {
                    // 判断是否为全角字符（通常汉字、中文标点是全角）
                    if (c >= 0x4E00 && c <= 0x9FFF || // CJK Unified Ideographs
                        c >= 0x3000 && c <= 0x303F || // CJK Symbols and Punctuation
                        c >= 0xFF00 && c <= 0xFFEF)   // Fullwidth forms
                    {
                        width += 2;
                    }
                    else
                    {
                        width += 1;
                    }
                }
                else
                {
                    width += 1; // 默认按半角处理
                }
            }
            return width;
        }
        static string FormatTableForMonospace(List<string[]> rows, int columnWidth = 0)
        {
            if (rows == null || rows.Count == 0) return "";

            int colCount = rows[0].Length;
            // 计算每列的最大显示宽度（以英文字符位为单位）
            var maxWidths = new int[colCount];
            for (int i = 0; i < colCount; i++)
            {
                if (columnWidth > 0)
                {
                    maxWidths[i] = columnWidth;
                }
                else
                    maxWidths[i] = rows.Max(row => GetDisplayWidth(row[i] ?? ""));
            }

            var result = new List<string>();
            foreach (var row in rows)
            {
                var cells = new string[colCount];
                for (int i = 0; i < colCount; i++)
                {
                    string cell = row[i] ?? "";
                    int padding = maxWidths[i] - GetDisplayWidth(cell);
                    cells[i] = cell + new string(' ', Math.Max(0, padding)); // 左对齐
                }
                result.Add(string.Join(" ", cells));
            }
            return string.Join(Environment.NewLine, result);
        }
    }
}
