using Baidu.Aip.Speech;
using CallCenterApi.IRepositories;
using MadRunFabric.Common;
using MadRunFabric.Model.CallCenterApi;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

namespace CallCenterApi.Controllers
{
    /// <summary>
    /// 音频文件转汉字
    /// </summary>
    [ApiVersion("6.0")]
    [Produces("application/json")]
    [Route("api/[controller]")]
    public class RecordsController : BaseController
    {
        private readonly ILogger<RecordsController> _logger;
        private readonly ICall_RecordsRepository _call_recordsRepository;

        public RecordsController(ILogger<RecordsController> logger, ICall_RecordsRepository call_recordsRepository)
        {
            _call_recordsRepository = call_recordsRepository;
            _logger = logger;
        }

        // GET: Records
        public ActionResult Index()
        {
            return View();
        }

        //语音识别
        private Asr _asrClient;//readonly
        //语音合成
        //private Tts _ttsClient;//readonly
        //验证身份参数
        //string strAK = "PuGGxl9vGrdijDTBYFBhEdVx";
        //string strSK = "aGmyOET05Os0atXBxFWXsC9qf1GgXv6R";
        string strappid = "14711628";
        string strAK = "OmUiGeYAxgyDjmjEY1bzQVls";
        string strSK = "IpiCKRjCz4K0jhQieOtTt8ofAyaEzEa8";
        string backdata = "";


        
        [HttpGet("getdata")]
        public async Task<IActionResult> GetData(string callid, string filepath)
        {
            //ActionResult res = NoToken("未知错误，请重新登录");
            //if (Request.IsAuthenticated)
            //{            
            _asrClient = new Asr(strappid,strAK, strSK);
            //_ttsClient = new Tts("PuGGxl9vGrdijDTBYFBhEdVx", "aGmyOET05Os0atXBxFWXsC9qf1GgXv6R");
            if (Init(callid, filepath))
            {
                return Success("音频文件转换成功", backdata);
            }
            else
            {
                return Error("转换失败！");
            }
            // }
            //return res;
        }


        public bool Init(string callid, string filepath)
        {
            //通过读取配置文件，获取数据库
            //string dbpath = System.Threading.Thread.GetDomain().BaseDirectory + @"bin\Config.ini";//Environment.CurrentDirectory + @"\Config.ini";  //指定ini文件的路径

            //IniFile ini = new IniFile(dbpath);
            //string _dbset = ini.IniReadValue("基础设置SQL", "Catalog");
            //string _url = ini.IniReadValue("基础设置", "服务器地址");
            //通过读取数据库，获得URL
            //DataTable dt_Recor = DbHelperSQL.Query("select FilePath,CallId from T_Call_CallRecords where IsTranslate!=1 ").Tables[0];
            //if (dt_Recor.Rows.Count > 0)
            //{
                //int i = 0;
                //foreach (DataRow dr in dt_Recor.Rows)
                //{
                    //录音记录id
                    //string callid = dr[1].ToString();
                    //录音记录URL路径
                    //string filepath = dr[0].ToString();
                    if (!string.IsNullOrEmpty(filepath))
                    {
                        //通过cmd执行ffmpeg改变音频采样率
                        Process p = new Process();
                        p.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + "cmd.exe";
                        p.StartInfo.UseShellExecute = false;
                        p.StartInfo.RedirectStandardOutput = true;
                        p.StartInfo.RedirectStandardInput = true;
                        p.StartInfo.RedirectStandardError = true;
                        p.StartInfo.CreateNoWindow = true;

                        string ffmpegLocation = System.Threading.Thread.GetDomain().BaseDirectory;

                        //string[] filepaths = filepath.Split(new char[] { '\\' });

                        //string res_audiopath = filepath.Replace(filepath.Substring(0, 2), _url).Replace("mp3", "wav").Replace(@"\", @"/");

                        if (this.AsrDataAsync(p, ffmpegLocation, filepath , callid).Result)//if (this.AsrDataAsync(p, ffmpegLocation, res_audiopath, callid).Result )
                { return true; }
                        else
                        { return false; }
                    }
                //}
            //}
            
             return false; 
        }
        /// <summary>
        /// 识别本地文件
        /// </summary>
        public async Task<bool> AsrDataAsync(Process p, string filelocation, string filepath, string callid)
        {
            #region 读取本地文件
            //int audiocounts = SplitAudio(filepath);

            ////读取结果
            //string rec_result = string.Empty;

            ////WebClient _wClient = new WebClient();
            ////byte[] p_pcm = _wClient.DownloadData("http://192.168.5.7:88/CallREC/luyin/20170508/1004/453_1004_173534.mp3");

            ////读取远端文件是否存在
            ////if (!RemoteFileExists("http://192.168.5.7:88/CallREC/luyin/20170908/1/427_1_141423.wav"))
            ////    return;
            ////ffmpeg -i http://192.168.5.7:88/callrec/luyin/20170506/1200/4_1200_164414.mp3 -f wav -ar 16000 -ac 1 -ab 16 D:\项目\XFTest_WITHDB\XFTest\bin\Debug\temp_voices\4_1200_164414.wav

            //string temp_filename = filepath.Split('\\').Last().Split('.')[0] + "_temp_";
            //Console.Write("\n开始语音听写 ...\n");
            //for (int i = 0; i < audiocounts; i++)
            //{
            //    p.Start();
            //    //先进入cmd命令
            //    //再打开FFmpeg.exe

            //    //p.StandardInput.WriteLine("exit");
            //    p.StandardInput.WriteLine("cd d/ " + filelocation + "ffmpeg.exe");
            //    p.StandardInput.WriteLine(filelocation.TrimEnd('\\'));

            //    //p.StandardInput.WriteLine("ffmpeg -i " + temp_filename + i + ".mp3 -f pcm -ar 16000 -ac 1 -ab 16 " + namepart.Replace(@"/", @"\"));
            //    string changefile = "ffmpeg -i " + filelocation + temp_filename + i + ".mp3 -f wav -ar 16000 -ac 1 -ab 16 " + filelocation + temp_filename + i + ".wav";

            //    p.StandardInput.WriteLine(changefile);
            //    Thread.Sleep(3000);
            //    p.StandardInput.WriteLine("exit");
            //    //Kill 是终止没有图形化界面的进程的唯一方法。
            //    p.Kill();
            //    //此处可以返回一个字符串，此例是返回压缩成功之后的一个文件路径
            //    var data = File.ReadAllBytes(filelocation + temp_filename + i + ".wav");
            //    var result_Json = _asrClient.Recognize(data, "wav", 16000);
            //    if (rec_result != null)
            //    {
            //        int _code = int.Parse(result_Json["err_no"].ToString());
            //        if (_code == 0)
            //        {
            //            string _res = result_Json["result"].ToString();
            //            rec_result += _res.TrimStart('[').TrimEnd(']');
            //        }
            //        else
            //        {
            //            string _msg = result_Json["err_msg"].ToString();
            //            rec_result += _msg;
            //        }
            //    }
            //}

            //Console.Write("\n语音听写结束\n");
            //Console.Write("=============================================================\n");
            //Console.Write(rec_result);
            //Console.Write("\n=============================================================\n");
            //int exe_res = Common.SQLHelper.Execute("XTZHSW_copy", "update T_Call_CallRecords set OperateObject='1',Remark='" + rec_result + "' where CallId='" + callid + "'", CommandType.Text, null);
            //if (exe_res > 0)
            //{
            //    Console.WriteLine("\n数据库更新成功\n");
            //    //操作完删除转换后的文件
            //    if (File.Exists(filelocation + namepart.Replace(@"/", @"\")))
            //    {
            //        File.Delete(filelocation + namepart.Replace(@"/", @"\"));
            //    }
            //}
            #endregion

            #region 读取URL中的文件
            //读取结果
            string rec_result = string.Empty;
            //读取远端文件是否存在
            if (!RemoteFileExists(filepath))
                return false ;
            int audiocounts = SplitAudio(filepath);
            if (audiocounts == 0)
            {
                return false;
             }
            string temp_filename = filepath.Split('/').Last().Split('.')[0] + "_temp_";
            Console.Write("\n开始语音听写 ...\n");
            for (int i = 0; i < audiocounts; i++)
            {
                p.Start();
                p.StandardInput.WriteLine("cd "+filelocation);
                p.StandardInput.WriteLine("ffmpeg.exe");
                
                //string changefile = "ffmpeg -i " + filelocation  + temp_filename + i + ".wav -acodec pcm_s16le -f s16le -ar 16000 -ac 1 " + filelocation  + temp_filename + i + ".pcm";
                string changefile = "ffmpeg -i " + filelocation + temp_filename + i + ".wav -acodec pcm_s16le -f s16le -ar 16000 -ac 1 " + filelocation + temp_filename + i + ".pcm";

                p.StandardInput.WriteLine(changefile);
                Thread.Sleep(3000);
                p.StandardInput.WriteLine("exit");
                //Kill 是终止没有图形化界面的进程的唯一方法。
                //p.Kill();
                //此处可以返回一个字符串，此例是返回压缩成功之后的一个文件路径
                var data = System.IO.File.ReadAllBytes(filelocation + temp_filename + i + ".pcm");
                var result_Json = _asrClient.Recognize(data, "pcm", 16000);//16000
                if (rec_result != null)
                {
                    int _code = int.Parse(result_Json["err_no"].ToString());
                    if (_code == 0)
                    {
                        string _res = result_Json["result"].ToString();
                        rec_result += _res.TrimStart('[').TrimEnd(']');
                    }
                    else
                    {
                        string _msg = result_Json["err_msg"].ToString();
                        rec_result += _msg;
                    }
                }
            }
            backdata = rec_result;
            
            //int exe_res = DbHelperSQL.ExecuteSql("update T_Call_CallRecords set IsTranslate=1,RecordsContent='" + rec_result + "' where CallId='" + callid + "'");
            #region 更新数据库
            var list = new List<FilterDefinition<mw_call_records>>();
            var filterBuilder = Builders<mw_call_records>.Filter;
            list.Add(filterBuilder.Eq("id", callid));
            var filter = Builders<mw_call_records>.Filter.And(list);
            var count = await _call_recordsRepository.CountAsync(filter);
            bool su = false;
            if (count > 0)
            {
                var dModel = await _call_recordsRepository.GetSingle(s => s.id.Equals(callid), null);
                dModel.istranslate = 1;
                dModel.recordscontent = rec_result;
                su = await _call_recordsRepository.Update(dModel);
                
            }
            #endregion
            if (su)
            {
                //删除转换时缓存文件
                for (int i = 0; i < audiocounts; i++)
                {
                    if (System.IO.File.Exists(filelocation  + temp_filename + i + ".wav"))
                    {
                        System.IO.File.Delete(filelocation + temp_filename + i + ".wav");
                    }
                    if (System.IO.File.Exists(filelocation  + temp_filename + i + ".pcm"))
                    {
                        System.IO.File.Delete(filelocation  + temp_filename + i + ".pcm");
                    }
                }
            }
            return true;
            #endregion
        }

        /// <summary>
        /// 分割音频
        /// </summary>
        /// <param name="filepath">音频路径</param>
        private int SplitAudio(string filepath)
        {
            //获取音频时长
            string length = "";
            string[] sumlength;
            int sec = 0;
            DateTime beginTime = DateTime.Parse("00:00:00");
            int index = 1;
            using (Process pro = new Process())
            {
                pro.StartInfo.UseShellExecute = false;
                pro.StartInfo.ErrorDialog = false;
                pro.StartInfo.RedirectStandardError = true;

                pro.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + "ffmpeg.exe";
                pro.StartInfo.Arguments = " -i " + filepath;

                pro.Start();
                StreamReader errorreader = pro.StandardError;
                pro.WaitForExit(1000);

                string result = errorreader.ReadToEnd();
                if (!string.IsNullOrEmpty(result))
                {
                    result = result.Substring(result.IndexOf("Duration: ") + ("Duration: ").Length, ("00:00:00").Length);
                    //result = "00:01:16";
                    length = result;
                    sumlength = length.Split(':');
                    sec += (int.Parse(sumlength[0].ToString()) * 60 * 60 + int.Parse(sumlength[1].ToString()) * 60 + int.Parse(sumlength[2].ToString()));
                }
            }
            //对音频进行分割
            //ffmpeg -ss 00:00:00 -i input.mp4 -c copy -t 60 output.mp4
            if (sec > 30) //(sec > 30)
            {
                Process p = new Process();
                p.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + "cmd.exe";//"cmd.exe";
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardInput = true;
                p.StartInfo.RedirectStandardError = true;
                p.StartInfo.CreateNoWindow = false;
                p.Start();
                string ffmpegLocation = System.Threading.Thread.GetDomain().BaseDirectory;

                p.StandardInput.WriteLine("cd " + ffmpegLocation.TrimEnd('\\'));
                p.StandardInput.WriteLine("ffmpeg.exe");
                p.StandardInput.AutoFlush = true;

                string fileName = System.IO.Path.GetFileName(filepath).Split('.')[0];
                index = sec / 28 + 1;

                for (int i = 0; i < index; i++)
                {
                    string splitstr = "ffmpeg -i " + filepath + " -ss " + beginTime.ToLongTimeString() + " -t 28 -acodec copy " + ffmpegLocation + fileName + "_temp_" + i + "." + System.IO.Path.GetFileName(filepath).Split('.')[1];
                    p.StandardInput.WriteLine(splitstr);
                    beginTime = beginTime.AddSeconds(29);
                    Thread.Sleep(3000);
                }
                p.StandardInput.WriteLine("exit");
                //Kill 是终止没有图形化界面的进程的唯一方法。
                //p.Kill();
            }
            else
            { return 0; }
            return index;
        }

        /// <summary>  
        /// 判断远程文件是否存在  
        /// </summary>  
        /// <param name="fileUrl"></param>  
        /// <returns></returns>  
        public static bool RemoteFileExists(string fileUrl)
        {
            HttpWebRequest re = null;
            HttpWebResponse res = null;
            try
            {
                re = (HttpWebRequest)WebRequest.Create(fileUrl);
                res = (HttpWebResponse)re.GetResponse();
                if (res.ContentLength != 0)
                {
                    //MessageBox.Show("文件存在");  
                    return true;
                }
            }
            catch (Exception)
            {
                //MessageBox.Show("无此文件");  
                return false;
            }
            finally
            {
                if (re != null)
                {
                    re.Abort();//销毁关闭连接  
                }
                if (res != null)
                {
                    res.Close();//销毁关闭响应  
                }
            }
            return false;
        }
    }
}