using Adaptation.Shared;
using Adaptation.Shared.Metrology;
using Adaptation.Shared.Properties;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Adaptation.FileHandlers.OpenInsightMetrologyViewer;

public class WSRequest
{

    public int Id { get; set; }
    public string Batch { get; set; }
    public string Cassette { get; set; }
    public string CellName { get; set; }
    public string Date { get; set; }
    public string FilePath { get; set; }
    public string MeanThickness { get; set; }
    public string Operator { get; set; }
    public string PSN { get; set; }
    public string RDS { get; set; }
    public string Reactor { get; set; }
    public string Recipe { get; set; }
    public string StdDev { get; set; }
    public string Title { get; set; }
    public string UniqueId { get; set; }
    public List<Stratus.Detail> Details { get; protected set; }

    [Obsolete("For json")] public WSRequest() { }

#pragma warning disable IDE0060
    internal WSRequest(IFileRead fileRead, Logistics logistics, List<Stratus.Description> descriptions, string processDataStandardFormat = null)
#pragma warning restore IDE0060
    {
        Id = -1;
        FilePath = string.Empty;
        CellName = logistics.MesEntity;
        if (descriptions[0] is not Stratus.Description x)
            throw new Exception();
        Details = new List<Stratus.Detail>();
        //Header
        {
            Batch = x.Lot;
            Cassette = x.Cassette;
            Date = x.Date;
            MeanThickness = x.MeanThickness;
            Operator = x.Employee;
            PSN = x.PSN;
            RDS = x.RDS;
            Reactor = x.Reactor;
            Recipe = x.Recipe;
            StdDev = x.GradeStdDev;
            Title = x.Title;
            UniqueId = x.UniqueId;
        }
        string[] segments;
        Stratus.Detail detail;
        foreach (Stratus.Description description in descriptions)
        {
            detail = new Stratus.Detail
            {
                HeaderUniqueId = description.HeaderUniqueId,
                Mean = description.Mean,
                PassFail = description.PassFail,
                Position = description.Position,
                Recipe = description.Recipe,
                Slot = description.Slot,
                StdDev = description.StdDev,
                Thickness = description.Thickness,
                UniqueId = description.UniqueId,
                Wafer = description.Wafer,
                Points = new()
            };
            segments = description.Position.Split(',');
            foreach (string segment in segments)
                detail.Points.Add(new Stratus.Point { HeaderUniqueId = description.HeaderUniqueId, UniqueId = description.UniqueId, Position = segment });
            segments = description.Thickness.Split(',');
            if (detail.Points.Count != segments.Length)
                throw new Exception();
            for (int i = 0; i < detail.Points.Count; i++)
                detail.Points[i].Thickness = segments[i];
            Details.Add(detail);
        }
        Date ??= logistics.DateTimeFromSequence.ToString();
        UniqueId = $"{logistics.JobID}_{logistics.MID}_{logistics.DateTimeFromSequence:yyyyMMddHHmmssffff}";
        for (int i = 0; i < Details.Count; i++)
        {
            Details[i].HeaderUniqueId = UniqueId;
            Details[i].UniqueId = $"{logistics.JobID}_{logistics.MID}_{logistics.DateTimeFromSequence:yyyyMMddHHmmssffff}_Item-{i + 1}";
        }
    }

    internal static long GetHeaderId(IFileRead fileRead, Logistics logistics, string openInsightMetrologyViewerAPI, string openInsightMetrologyViewerFileShare, int weekOfYear, WS.Results results, List<Stratus.Description> descriptions)
    {
        long result;
        if (results is not null && results.HeaderId is not null)
            result = results.HeaderId.Value;
        else
        {
            WSRequest wsRequest = new(fileRead, logistics, descriptions);
            string directory = Path.Combine(openInsightMetrologyViewerFileShare, logistics.DateTimeFromSequence.Year.ToString(), $"WW{weekOfYear:00}");
            (_, WS.Results wsResults) = WS.SendData(openInsightMetrologyViewerAPI, logistics.Sequence, directory, wsRequest);
            if (wsResults.Success is null || !wsResults.Success.Value)
                throw new Exception(wsResults.ToString());
            result = wsResults.HeaderId.Value;
        }
        return result;
    }

#pragma warning disable IDE0060
    internal static void PostOpenInsightMetrologyViewerAttachments(IFileRead fileRead, Logistics logistics, string openInsightMetrologyViewerAPI, string originalDataBioRad, List<Stratus.Description> descriptions, string matchDirectory, WS.Results results, string headerIdDirectory)
#pragma warning restore IDE0060
    {
        string dataPDFFile = Path.Combine(matchDirectory, $"{results.HeaderId}.pdf");
        string[] txtFiles = Directory.GetFiles(matchDirectory, string.Concat(originalDataBioRad, "*.txt"), SearchOption.TopDirectoryOnly);
        if (txtFiles.Length != 1)
            throw new Exception($"Invalid source file count for <{results.HeaderId}>!");
        string[] lines = File.ReadAllLines(txtFiles[0]);
        lines = (from l in lines where !string.IsNullOrEmpty(l) select l).ToArray();
        if (lines.Length > 1)
        {
            org.apache.pdfbox.pdmodel.PDDocument pdDocument = new();
            org.apache.pdfbox.pdmodel.PDPage pdPage = new();
            pdDocument.addPage(pdPage);
            org.apache.pdfbox.pdmodel.edit.PDPageContentStream pdPageContentStream = new(pdDocument, pdPage);
            org.apache.pdfbox.pdmodel.font.PDFont pdFont = org.apache.pdfbox.pdmodel.font.PDType1Font.HELVETICA;
            pdPageContentStream.setFont(pdFont, 16);
            for (int i = 1; i < lines.Length; i++)
            {
                pdPageContentStream.beginText();
                pdPageContentStream.moveTextPositionByAmount(16, 750 - (i * 16));
                pdPageContentStream.drawString(lines[i]);
                pdPageContentStream.endText();
            }
            pdPageContentStream.close();
            pdDocument.save(dataPDFFile);
            pdDocument.close();
            List<WS.Attachment> headerAttachments = new()
            {
                new WS.Attachment(results, headerIdDirectory, $"{logistics.JobID}_{logistics.MID}_{logistics.DateTimeFromSequence:yyyyMMddHHmmssffff}", "Data.pdf", dataPDFFile)
            };
            WS.AttachFiles(openInsightMetrologyViewerAPI, headerAttachments, dataAttachments: null);
        }
    }

}