using System;
using System.Configuration;
using System.IO;
using System.Linq;
using Ancode.Ans.Tiss.Domain.Model.Entities.V30500;
using Ancode.Ans.Tiss.WebService.Extensions;
using Ancode.Ans.Tiss.WebService.Helpers;
using Ancode.Ans.Tiss.WebService.Integration.Entities;

namespace Ancode.Ans.Tiss.WebService._30500
{
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.8.3928.0")]
    [System.Web.Services.WebServiceAttribute(Namespace = "http://www.ans.gov.br/tiss/ws/tipos/tisssolicitacaoprocedimento/v30500")]
    [System.Web.Services.WebServiceBindingAttribute(Name = "tissSolicitacaoProcedimento_Binding", Namespace = "http://www.ans.gov.br/tiss/ws/tipos/tisssolicitacaoprocedimento/v30500")]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(SignatureType))]
    [System.Xml.Serialization.XmlIncludeAttribute(typeof(ctm_solicitacaoLote))]
    public class tissSolicitacaoProcedimento : System.Web.Services.WebService
    {
        [System.Web.Services.WebMethodAttribute()]
        [System.Web.Services.Protocols.SoapDocumentMethodAttribute("", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
        [return: System.Xml.Serialization.XmlElementAttribute("autorizacaoProcedimentoWS", Namespace = "http://www.ans.gov.br/padroes/tiss/schemas")]
        public autorizacaoProcedimentoWS tissSolicitacaoProcedimento_Operation([System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.ans.gov.br/padroes/tiss/schemas")] solicitacaoProcedimentoWS solicitacaoProcedimentoWS)
        {
            var spsadtSolicitacaoGuia = solicitacaoProcedimentoWS.solicitacaoProcedimento.Item as ctm_spsadtSolicitacaoGuia;

            var requisicaoSpSadt = new RequisicaoSpSadt(spsadtSolicitacaoGuia);

            var csvSeparator = ConfigurationManager.AppSettings["CsvSeparator"];

            var requisicaoSpSadtCsv = CsvHelper.ToCsv<RequisicaoSpSadt>(requisicaoSpSadt, csvSeparator);

            var requisicaoCabecalhoPrestador = solicitacaoProcedimentoWS.cabecalho.origem.Item as cabecalhoTransacaoOrigemIdentificacaoPrestador;

            var fileName = $"{solicitacaoProcedimentoWS.cabecalho.identificacaoTransacao.tipoTransacao}-{requisicaoCabecalhoPrestador?.Item}-{solicitacaoProcedimentoWS.cabecalho.identificacaoTransacao.sequencialTransacao}.txt";

            var pathReq = ConfigurationManager.AppSettings["ReqTxt"];

            using (var outputFile = new StreamWriter(Path.Combine(pathReq, fileName)))
            {
                outputFile.Write(requisicaoSpSadtCsv);
            }

            var pathRet = ConfigurationManager.AppSettings["RetTxt"];
            
            var hasFile = false;
            var count = 0;

            while (!hasFile)
            {
                count += 1;
                if (count > 60)
                    throw new TimeoutException();

                System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));

                hasFile = File.Exists(Path.Combine(pathRet, fileName));
            }

            string retornoSpSadtCsv;

            using (var sr = new StreamReader(Path.Combine(pathRet, fileName)))
            {
                retornoSpSadtCsv = sr.ReadToEnd();
            }

            File.Delete(Path.Combine(pathRet, fileName));

            var retornoSpSadt = new RetornoSpSadt(retornoSpSadtCsv, csvSeparator);

            ct_motivoGlosa[] motivosNegativa = null;
            ct_autorizacaoDados dadosAutorizacao;
            dm_statusSolicitacao statusSolicitacao;

            if (retornoSpSadt.Status == "1" || !string.IsNullOrWhiteSpace(retornoSpSadt.CodigoGlosa))
            {
                statusSolicitacao = dm_statusSolicitacao.Item3;

                dadosAutorizacao = new ct_autorizacaoDados
                {
                    numeroGuiaPrestador = null,
                    numeroGuiaOperadora = null,
                    dataAutorizacaoSpecified = false,
                    senha = null,
                    dataValidadeSenhaSpecified = false
                };

                if (!Enum.TryParse($"Item{retornoSpSadt.CodigoGlosa}", out dm_tipoGlosa tipoGlosa))
                {
                    tipoGlosa = dm_tipoGlosa.Item;
                }

                motivosNegativa = new[]
                {
                    new ct_motivoGlosa
                    {
                        codigoGlosa = tipoGlosa,
                        descricaoGlosa = $"{retornoSpSadt.CodigoGlosa} {retornoSpSadt.DescricaoGlosa.RemoverCaracteresEspeciais()}"
                    }
                };
            }
            else
            {
                statusSolicitacao = dm_statusSolicitacao.Item1;

                dadosAutorizacao = new ct_autorizacaoDados
                {
                    numeroGuiaPrestador = retornoSpSadt.NumeroGuiaPrestador,
                    numeroGuiaOperadora = retornoSpSadt.NumeroGuiaOperadora,
                    dataAutorizacao = DateTime.Now,
                    dataAutorizacaoSpecified = true,
                    senha = retornoSpSadt.NumeroGuiaOperadora,
                    dataValidadeSenha = DateTime.Now.AddDays(90),
                    dataValidadeSenhaSpecified = true
                };
            }

            var autorizacaoProcedimentoWs = new autorizacaoProcedimentoWS
            {
                cabecalho = new cabecalhoTransacao
                {
                    identificacaoTransacao = new cabecalhoTransacaoIdentificacaoTransacao
                    {
                        tipoTransacao = solicitacaoProcedimentoWS.cabecalho.identificacaoTransacao.tipoTransacao,
                        sequencialTransacao = solicitacaoProcedimentoWS.cabecalho.identificacaoTransacao.sequencialTransacao,
                        dataRegistroTransacao = solicitacaoProcedimentoWS.cabecalho.identificacaoTransacao.dataRegistroTransacao,
                        horaRegistroTransacao = solicitacaoProcedimentoWS.cabecalho.identificacaoTransacao.horaRegistroTransacao
                    },
                    origem = new cabecalhoTransacaoOrigem
                    {
                        Item = solicitacaoProcedimentoWS.cabecalho.destino.Item
                    },
                    destino = new cabecalhoTransacaoDestino
                    {
                        Item = new ct_prestadorIdentificacao
                        {
                            Item = requisicaoCabecalhoPrestador?.Item,
                            ItemElementName = requisicaoCabecalhoPrestador.ItemElementName
                        }
                    },
                    Padrao = solicitacaoProcedimentoWS.cabecalho.Padrao
                },
                autorizacaoProcedimento = new ct_situacaoAutorizacao
                {
                    Item = new ctm_autorizacaoServico
                    {
                        dadosAutorizacao = dadosAutorizacao,
                        tipoEtapaAutorizacao = dm_etapasAutorizacao.Item1,
                        dadosBeneficiario = spsadtSolicitacaoGuia?.dadosBeneficiario,
                        statusSolicitacao = statusSolicitacao,
                        servicosAutorizados = new[]
                        {
                            new ct_procedimentoAutorizado
                            {
                                sequencialItem = "1",
                                procedimento = spsadtSolicitacaoGuia?.procedimentosSolicitados.FirstOrDefault()?.procedimento,
                                quantidadeSolicitada = spsadtSolicitacaoGuia?.procedimentosSolicitados.FirstOrDefault()?.quantidadeSolicitada,
                                quantidadeAutorizada = retornoSpSadt.QuantidadeAutorizada,
                                motivosNegativa = motivosNegativa
                            }
                        }

                    }
                }
            };

            return autorizacaoProcedimentoWs;
        }
    }
}
