using Microsoft.AspNetCore.Mvc;
using LAPS_XMLQC_Service.Services;
using System.IO;
using System.Xml.Xsl;
using System.Xml;
using System;
using System.Collections.Generic;

namespace LAPS_XMLQC_Service.Controllers.XmlValidator
{
    [Route("api/[controller]")]
    [ApiController]
    public class XmlValidatorApiController : ControllerBase
    {
        private readonly XmlValidatorService _xmlValidator;
        public XmlValidatorApiController(XmlValidatorService xmlValidatorService)
        {
            _xmlValidator = xmlValidatorService;
        }

        [HttpGet("document-path")]
        public ActionResult<string> GetDocumentPath(string documentType, string projectDefinitionId)
        {
            string filepath = _xmlValidator.GetDocumentPath(documentType, Convert.ToInt32(projectDefinitionId));          

            return Ok(filepath);
        }


        /// <summary>
        /// Validates XML against a DTD file.
        /// </summary>
        /// <param name="xmlContent">The XML content as a string.</param>
        /// <param name="dtdFilePath">The path to the DTD file.</param>
        /// <returns>A list of validation errors or a success message.</returns>
        [HttpPost("validate-dtd")]
        public IActionResult ValidateXmlAgainstDtd([FromBody] XmlValidationRequest request)
        {
            if (string.IsNullOrEmpty(request.XmlContent) || string.IsNullOrEmpty(request.SchemaFilePath))
            {
                return BadRequest("XML content and DTD file path are required.");
            }

            if (!System.IO.File.Exists(request.SchemaFilePath))
            {
                return NotFound("DTD file not found at the specified path.");
            }

            var validationErrors = _xmlValidator.ValidateXmlAgainstDtd(request.XmlContent, request.SchemaFilePath);

            return Ok(validationErrors);
        }

        /// <summary>
        /// Validates XML against an XSD file.
        /// </summary>
        /// <param name="xmlContent">The XML content as a string.</param>
        /// <param name="xsdFilePath">The path to the XSD file.</param>
        /// <returns>A list of validation errors or a success message.</returns>
        [HttpPost("validate-xsd")]
        public IActionResult ValidateXmlAgainstXsd([FromBody] XmlValidationRequest request)
        {
            if (string.IsNullOrEmpty(request.XmlContent) || string.IsNullOrEmpty(request.SchemaFilePath))
            {
                return BadRequest("XML content and XSD file path are required.");
            }

            if (!System.IO.File.Exists(request.SchemaFilePath))
            {
                return NotFound("XSD file not found at the specified path.");
            }

            var validationErrors = _xmlValidator.ValidateXmlAgainstXsd(request.XmlContent, request.SchemaFilePath);

            return Ok(validationErrors);
        }

        [HttpPost("convert-text")]
        public IActionResult ConvertXmlToText([FromBody] XmlValidationRequest request)
        {
            try
            {
                var validationErrors = new List<string>();

                if (string.IsNullOrEmpty(request.XmlContent) || string.IsNullOrEmpty(request.SchemaFilePath))
                {
                    return BadRequest("XML content and XSLT file path are required.");
                }

                if (!System.IO.File.Exists(request.SchemaFilePath))
                {
                    return NotFound("XSLT file not found at the specified path.");
                }

                // Load XML content
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.LoadXml(request.XmlContent);

                // Prepare output file path
                request.FileName = request.FileName + ".txt";
                string outputFilePath = Path.Combine(request.OutputPath.Replace(@"\IN", @"\OUT"), request.FileName);

                // Configure XmlWriterSettings to allow XML fragments
                XmlWriterSettings settings = new XmlWriterSettings
                {
                    ConformanceLevel = ConformanceLevel.Fragment, // Allows fragments
                    Indent = true // Optional: for better readability
                };

                // Apply the transformation
                XslCompiledTransform xslt = new XslCompiledTransform();
                xslt.Load(request.SchemaFilePath);

                using (StreamWriter writer = new StreamWriter(outputFilePath))
                using (XmlWriter xmlWriter = XmlWriter.Create(writer, settings)) // Use settings here
                {
                    xslt.Transform(xmlDocument, xmlWriter);
                }

                // Read the generated file content
                string fileContent = string.Empty;
                using (StreamReader reader = new StreamReader(outputFilePath))
                {
                    fileContent = reader.ReadToEnd();
                }

                if (validationErrors.Count == 0)
                {
                    validationErrors.Add("XML is successfully transformed into a text file.");
                }

                // Return the file content as part of the response
                return Ok(new
                {
                    Messages = validationErrors,
                    FileContent = fileContent
                });
            }
            catch (XmlException ex)
            {
                return BadRequest($"Invalid XML: {ex.Message}");
            }
            catch (XsltException ex)
            {
                return BadRequest($"XSLT Error: {ex.Message}");
            }
            catch (Exception ex)
            {
                return BadRequest($"An error occurred: {ex.Message}");
            }

        }

    }

    // Model to capture XML and Schema content for validation
    public class XmlValidationRequest
    {
        public string XmlContent { get; set; }
        public string SchemaFilePath { get; set; }    
        public string OutputPath { get; set; }
        public string FileName { get; set; }
    }
   

}
