using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Dapper;
using Microsoft.Data.SqlClient;
using static ad_login.Controllers.ApiController;
using static DbTableClass;
using Dapper.Contrib.Extensions;

namespace ad_login.Controllers
{
    [Route("BackEndApi")]
    public class BackEndApiController : ControllerBase
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        DbConn dbConn = new DbConn();
        SqlConnection conn = new SqlConnection(GlobalClass.appsettings("ConnectionStrings:SQLConnectionString"));

        public BackEndApiController(IHttpContextAccessor httpContextAccessor)
        {
            this._httpContextAccessor = httpContextAccessor;
        }

        [Route("newsAddEditDelGet")]
        public ActionResult NewsAddEditDelGet(IFormCollection obj) {
            newDetialResult ret = new newDetialResult();

            authToken token = new authToken(this._httpContextAccessor);

            if (token.user_isLogin == false)
            {
                HttpContext.Response.Cookies.Delete("token_key");
                ret.ret = "no";
                ret.err_code = "9999";
                ret.message = "非登入狀態!";
                return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
            }

            DbConn dbConn = new DbConn();
            SqlConnection conn = dbConn.sqlConnection();

            string news_uid = obj["news_uid"].ToString();
            string news_title = obj["news_title"].ToString();
            string news_subtitle = obj["news_subtitle"].ToString();
            string news_date = obj["news_date"].ToString();
            string news_mainPhoto = obj["news_mainPhoto"].ToString();
            string news_content = obj["news_content"].ToString();
            string TagsStr = obj["news_tags"].ToString().TrimEnd(',');
            string photoArrayJson = obj["photoArrayJson"].ToString().TrimEnd(',');

            string method = obj["method"].ToString();



            if (method == "get")
            {
                news newObj = conn.QueryFirstOrDefault<news>("select * from news where news_uid = @news_uid", new { news_uid = news_uid });

                if (newObj == null) {
                    ret.ret = "no";
                    ret.err_code = "1009";
                    ret.message = "無此news_uid資料!";
                    return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
                }

                ret.data = new newsDetial(newObj);
                ret.ret = "yes";
                return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
            }

            if (method == "")
            {
                ret.ret = "no";
                ret.err_code = "0001";
                ret.message = "無method參數!";
                return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
            }

            if (method == "del") {
                conn.Execute("delete photo where news_uid = @news_uid", new { news_uid = news_uid });
                conn.Execute("delete tag where news_uid = @news_uid", new { news_uid = news_uid });
                conn.Execute("delete news where news_uid = @news_uid", new { news_uid = news_uid });
               
                ret.ret = "yes";

                return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
            }

            string err_msg = "";

            if (news_title == "")
            {
                err_msg += "無標題!\n";
            }

            if (news_subtitle == "")
            {
                err_msg += "無副標題\n";
            }

            if (news_content == "")
            {
                err_msg += "無內文\n";
            }

            if (news_date == "")
            {
                err_msg += "無發布日期\n";
            }

            if (err_msg != "")
            {
                ret.ret = "no";
                ret.err_code = "0001";
                ret.message = err_msg;
                return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
            }

            if (method == "edit") {
                if (news_uid == "") {
                    ret.ret = "no";
                    ret.err_code = "0002";
                    ret.message = "無 news_uid";
                    return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
                }

                news objNew = conn.QueryFirstOrDefault<news>("select * from news where news_uid = @news_uid", new { news_uid = news_uid });

                if (objNew == null) {
                    ret.ret = "no";
                    ret.err_code = "0003";
                    ret.message = "無此 news_uid資料";
                    return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
                }

                dynamic photoJsonObj;

                try
                {
                    photoJsonObj = JsonConvert.DeserializeObject(photoArrayJson);
                }
                catch (Exception ex)
                {
                    ret.ret = "no";
                    ret.err_code = "0003";
                    ret.message = "photo json error" + ex.Message;
                    return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
                }

                conn.Execute("delete tag where news_uid = @news_uid", new { news_uid = news_uid });
                conn.Execute("delete photo where news_uid = @news_uid", new { news_uid = news_uid });

                string[] newsTagArr = TagsStr.Split(",");
                List<tag> newsTags = new List<tag>();
                foreach (string tag in newsTagArr)
                {
                    tags tagData = conn.QueryFirstOrDefault<tags>("select * from tags where tag_uid = @tag_uid", new { tag_uid = tag });

                    if (tagData != null)
                    {
                        tag newTag = new tag();
                        newTag.tag_uid = tagData.tag_uid;
                        newTag.news_uid = news_uid;
                        newTag.tag_text = tagData.tag_text;
                        newsTags.Add(newTag);
                    }
                }

                List<photo> photos = new List<photo>();

                foreach (dynamic item in photoJsonObj)
                {
                    photo photoObj = new photo();

                    photoObj.photo_uid = GlobalClass.CreateRandomCode(12);
                    photoObj.news_uid = news_uid;
                    photoObj.photo_title = item.photo_title;
                    photoObj.photo_path = item.photo_path;


                    photos.Add(photoObj);
                }

                objNew.news_title = news_title;
                objNew.news_date = news_date;
                objNew.news_subtitle = news_subtitle;
                objNew.news_content = news_content;
                objNew.news_mainPhoto = news_mainPhoto;
                objNew.news_modifydate = DateTime.Now;

                conn.Update<news>(objNew);
                conn.Insert(photos);
                conn.Insert(newsTags);

                ret.ret = "yes";
                ret.data = new newsDetial(objNew);
                return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
            }

            if (method == "add")
            {
                news_uid = "news_" + GlobalClass.CreateRandomCode(8);

                string[] newsTagArr = TagsStr.Split(",");
                List<tag> newsTags = new List<tag>();
                foreach (string tag in newsTagArr)
                {
                    tags tagData = conn.QueryFirstOrDefault<tags>("select * from tags where tag_uid = @tag_uid", new { tag_uid = tag });

                    if (tagData != null)
                    {
                        tag newTag = new tag();
                        newTag.tag_uid = tagData.tag_uid;
                        newTag.news_uid = news_uid;
                        newTag.tag_text = tagData.tag_text;
                        newsTags.Add(newTag);
                    }
                }

                dynamic photoJsonObj;

                try
                {
                    photoJsonObj = JsonConvert.DeserializeObject(photoArrayJson);
                }
                catch (Exception ex)
                {
                    ret.ret = "no";
                    ret.err_code = "0003";
                    ret.message = "photo json error" + ex.Message;
                    return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
                }

                List<photo> photos = new List<photo>();

                foreach (dynamic item in photoJsonObj)
                {
                    photo photoObj = new photo();

                    photoObj.photo_uid = GlobalClass.CreateRandomCode(12);
                    photoObj.news_uid= news_uid;
                    photoObj.photo_title = item.photo_title;
                    photoObj.photo_path = item.photo_path;


                    photos.Add(photoObj);
                }

                news objNew = new news();

                objNew.news_uid = news_uid;
                objNew.news_title = news_title;
                objNew.news_date = news_date;
                objNew.news_subtitle = news_subtitle;
                objNew.news_content = news_content;
                objNew.news_mainPhoto = news_mainPhoto;
              
                conn.Insert<news>(objNew);
                conn.Insert(photos);
                conn.Insert(newsTags);

                ret.ret = "yes";
                ret.data = new newsDetial(objNew);
                return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
            }

            return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
        }

        [Route("updateTags")]
        public ActionResult UpdateTags(IFormCollection obj)
        {
            updatTagResult ret = new updatTagResult();

            authToken token = new authToken(this._httpContextAccessor);
            if (token.user_isLogin == false)
            {
                HttpContext.Response.Cookies.Delete("token_key");

                return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
            }

            string search = obj["search"].ToString();

            if (search.Length < 2)
            {
                ret.ret = "no";
                return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
            }
            tags tag = conn.QueryFirstOrDefault<tags>("select * from tags where tag_text = @tag_text", new { tag_text = search });



            if (tag == null)
            {
                tags newTag = new tags();
                newTag.tag_uid = "tag_" + GlobalClass.CreateRandomCode(12);
                newTag.tag_text = search;

                conn.Insert<tags>(newTag);

                ret.data.id = newTag.tag_uid;
                ret.data.text = search;
                ret.ret = "yes";
            }
            else
            {
                ret.data.id = tag.tag_uid;
                ret.data.text = search;
                ret.ret = "yes";
            }
            return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
        }

        [Route("queryTags")]
        public ActionResult QueryTags(IFormCollection obj)
        {
            tagListResult ret = new tagListResult();

            authToken token = new authToken(this._httpContextAccessor);
            if (token.user_isLogin == false)
            {
                HttpContext.Response.Cookies.Delete("token_key");

                return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
            }

            string search = obj["search"].ToString();
            search = "%" + search + "%";
            List<tags> tagList = conn.Query<tags>("select * from tags where tag_text like @tag_text", new { tag_text = search }).ToList();

            foreach (tags tag in tagList)
            {
                optionData item = new optionData();

                item.id = tag.tag_uid;
                item.text = tag.tag_text;

                ret.data.Add(item);
            }

            return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
        }

        [Route("subPhotoUpload")]
        [RequestFormLimits(MultipartBodyLengthLimit = int.MaxValue)]
        [RequestSizeLimit(int.MaxValue)]
        public ActionResult SubPhotoUpload([FromForm(Name = "subPhoto")] IFormFile file)
        {
            authToken token = new authToken(this._httpContextAccessor);
            if (token.user_isLogin == false)
            {
                List<errFile> files = new List<errFile>();

                errFile newFile = new errFile();
                newFile.name = "";
                newFile.size = 0;
                newFile.error = "尚未登入";

                files.Add(newFile);

                fileResult obj = new fileResult();

                obj.files = files;

                return Content(JsonConvert.SerializeObject(files), "application/json;charset=utf-8");
            }


            string originFileName = file.FileName;
            string newFileName = "subPhoto_" + GlobalClass.CreateRandomCode(8) + Path.GetExtension(originFileName);
            string fullPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/upload/sub/" + newFileName);
            try
            {
                using (var stream = new FileStream(fullPath, FileMode.Create))
                {
                    file.CopyTo(stream);
                }

                List<uploadFile> files = new List<uploadFile>();

                uploadFile newFile = new uploadFile();

                newFile.name = originFileName;
                newFile.url = "/upload/sub/" + newFileName;
                newFile.size = file.Length;
                newFile.thumbnailUrl = "/upload/sub/" + newFileName;
                newFile.deleteUrl = "/upload/sub/" + newFileName;



                files.Add(newFile);

                fileResult obj = new fileResult();

                obj.files = files;





                return Content(JsonConvert.SerializeObject(obj), "application/json;charset=utf-8");
            }
            catch (Exception ex)
            {
                List<errFile> files = new List<errFile>();

                errFile newFile = new errFile();
                newFile.name = originFileName;
                newFile.size = file.Length;
                newFile.error = ex.Message;

                files.Add(newFile);

                fileResult obj = new fileResult();

                obj.files = files;

                return Content(JsonConvert.SerializeObject(files), "application/json;charset=utf-8");
            }
        }

        [Route("mainPhotoUpload")]
        [RequestFormLimits(MultipartBodyLengthLimit = int.MaxValue)]
        [RequestSizeLimit(int.MaxValue)]
        public ActionResult MainPhotoUpload([FromForm(Name = "avatar")] IFormFile file) {
            authToken token = new authToken(this._httpContextAccessor);
            if (token.user_isLogin == false)
            {
                List<errFile> files = new List<errFile>();

                errFile newFile = new errFile();
                newFile.name = "";
                newFile.size = 0;
                newFile.error = "尚未登入";

                files.Add(newFile);

                fileResult obj = new fileResult();

                obj.files = files;

                return Content(JsonConvert.SerializeObject(files), "application/json;charset=utf-8");
            }


            string originFileName = file.FileName;
            string newFileName = "mainPhoto_" + GlobalClass.CreateRandomCode(8) + Path.GetExtension(originFileName);
            string fullPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/upload/main/" + newFileName);
            try
            {
                using (var stream = new FileStream(fullPath, FileMode.Create))
                {
                    file.CopyTo(stream);
                }

                List<uploadFile> files = new List<uploadFile>();

                uploadFile newFile = new uploadFile();

                newFile.name = originFileName;
                newFile.url = "/upload/main/" + newFileName;
                newFile.size = file.Length;
                newFile.thumbnailUrl = "/upload/main/" + newFileName;
                newFile.deleteUrl = "/upload/main/" + newFileName;



                files.Add(newFile);

                fileResult obj = new fileResult();

                obj.files = files;





                return Content(JsonConvert.SerializeObject(obj), "application/json;charset=utf-8");
            }
            catch (Exception ex)
            {
                List<errFile> files = new List<errFile>();

                errFile newFile = new errFile();
                newFile.name = originFileName;
                newFile.size = file.Length;
                newFile.error = ex.Message;

                files.Add(newFile);

                fileResult obj = new fileResult();

                obj.files = files;

                return Content(JsonConvert.SerializeObject(files), "application/json;charset=utf-8");
            }
        }

        //後台登入
        [Route("signin")]
        public ActionResult Signin(IFormCollection obj)
        {
            result ret = new result();

            string input_ID = obj["id"].ToString();
            string input_PWD = obj["pwd"].ToString();

            string sys_ID = GlobalClass.appsettings("Admin:id");
            string sys_PWD = GlobalClass.Sha256(GlobalClass.appsettings("Admin:pwd"));

            if (input_ID == sys_ID && input_PWD == sys_PWD)
            {
                DbConn dbConn = new DbConn();

                SqlConnection conn = dbConn.sqlConnection();

                string token_key = GlobalClass.CreateRandomCode(24);

                int effCount = conn.Execute("insert into token (token_key, user_uid, user_id, user_perm, token_expireddate) values (@token_key, @user_uid, @user_id, @user_perm, @token_expireddate)", new { token_key = token_key, user_uid = "system", user_id = input_ID, user_perm = "system", token_expireddate = DateTime.Now.AddMinutes(20) });

                CookieOptions options = new CookieOptions();

                options.Secure = true;
                options.Expires = DateTime.Now.AddMinutes(30);

                HttpContext.Response.Cookies.Delete("token_key");

                _httpContextAccessor.HttpContext.Response.Cookies.Append("token_key", token_key, options);

                dbConn.closeConn();

                ret.ret = "yes";
            }
            else
            {
                ret.ret = "no";
                ret.err_code = "0001";
                ret.message = "帳號或密碼錯誤!";
            }

            return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
        }

        [Route("newsList")]
        public ActionResult NewsList(IFormCollection obj) {
            newResult ret = new newResult();

            authToken token = new authToken(this._httpContextAccessor);

            if (token.user_isLogin == false)
            {
                HttpContext.Response.Cookies.Delete("token_key");
                ret.ret = "no";
                ret.err_code = "9999";
                ret.message = "非登入狀態!";
                return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
            }

            DbConn dbConn = new DbConn();
            SqlConnection conn = dbConn.sqlConnection();

            ret.newsList = conn.Query<news>("select * from news order by news_sn desc").ToList();
            ret.ret = "yes";
            return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
        }

        public class newResult
        {
            public string ret = "no";
            public string err_code = "0000";
            public string message = "";
            public List<news> newsList = new List<news>();

        }

        public class newDetialResult
        {
            public string ret = "no";
            public string err_code = "0000";
            public string message = "";
            public newsDetial data = new newsDetial();
        }

        public class fileResult
        {
            public object files = new object();
        }

        public class uploadFile
        {
            public string name { get; set; } = "";
            public long size { get; set; } = 0;
            public string url { get; set; } = "";
            public string thumbnailUrl { get; set; } = "";
            public string deleteUrl { get; set; } = "";
            public string deleteType { get; set; } = "DELETE";
        }

        public class errFile
        {
            public string name { get; set; } = "";
            public long size { get; set; } = 0;
            public string error { get; set; } = "";
        }

        public class updatTagResult
        {
            public string ret { get; set; } = "no";
            public string err_code { get; set; } = "0000";
            public string message { get; set; } = "";

            public optionData data = new optionData();
        }
        public class tagListResult
        {
            public List<optionData> data = new List<optionData>();
        }

        public class optionData
        {
            public string id { get; set; } = "";
            public string text { get; set; } = "";
        }
    }
}
