using System.Net;

using HttpClientStudy.Model;
using HttpClientStudy.Service;

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OpenApi.Validations;

namespace HttpClientStudy.WebApp.Controllers
{
    /// <summary>
    /// 普通(简单) 控制器
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class NormalController : ControllerBase
    {
        private ILogger<SimpleController> _logger;
        private AccountService _accountService;

        /// <summary>
        /// 构造
        /// </summary>
        public NormalController(ILogger<SimpleController> logger, AccountService accountService)
        { 
            _logger = logger;
            _accountService = accountService;
        }

        #region GET

        /// <summary>
        /// 获取所有账号
        /// (无参数)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAllAccounts()
        {
            var accounts = _accountService.GetAllAccounts();

            var result = BaseResultUtil.Success(accounts);
            return Ok(result);
        }

        /// <summary>
        /// 查询账号
        /// (默认方式参数:URL传参)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAccount(int id)
        {
            var accounts = _accountService.GetAllAccounts();
            var account = accounts.FirstOrDefault(a => a.Id == id);

            var result = BaseResultUtil.Success(account);
            return Ok(result);
        }

        /// <summary>
        /// 查询账号
        /// (路由参数)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("{name}")]
        public IActionResult GetAccount([FromRoute] string name)
        {
            var accounts = _accountService.GetAllAccounts();
            var account = accounts.FirstOrDefault(a => a.Name == name);
            var result = BaseResultUtil.Success(account);
            return Ok(result);
        }

        /// <summary>
        /// 查询账号
        /// (中文参数)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAccountByName(string ChineseName, [FromQuery]string ChineseName2)
        {
            var accounts = _accountService
                .GetAllAccounts()
                .Where(a => a.Name == ChineseName || a.Name == ChineseName2)
                .ToList();

            var result = BaseResultUtil.Success(accounts);
            return Ok(result);
        }

        /// <summary>
        /// 查询账号
        /// (查询参数)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAccountByRole([FromQuery] string role)
        {
            var accounts = _accountService.GetAllAccounts();

            accounts = accounts.Where(accounts => accounts.Role == role).ToList();

            var result = BaseResultUtil.Success(accounts);
            return Ok(result);
        }

        /// <summary>
        /// 查询账号
        /// (请求头参数:中文,客户端Url编码后请求,此处Url解码后使用)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAccountFromHeader([FromHeader] string name)
        {
            //先Url解码
            var decodeName = WebUtility.UrlDecode(name);
            var account = _accountService.GetAllAccounts().Single(i => i.Name == decodeName);
            var result = BaseResultUtil.Success(account);
            return Ok(result);
        }

        /// <summary>
        /// 查询账号
        /// (服务注入参数)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAccountFromServices([FromServices] Account account)
        {
            var result = BaseResultUtil.Success(account);
            return Ok(result);
        }

        #endregion

        #region PUT
        /// <summary>
        /// Put请求 示例
        /// </summary>
        /// <returns></returns>
        [HttpPut]
        public IActionResult PutDemo(int id)
        {
            var accounts = _accountService.GetAllAccounts();
            var account = accounts.FirstOrDefault(a => a.Id == id);

            var result = BaseResultUtil.Success(account);
            return Ok(result);
        }
        #endregion

        #region HEAD
        /// <summary>
        /// Head请求 示例
        /// </summary>
        /// <returns></returns>
        [HttpHead]
        public IActionResult HeadDemo(int id)
        {
            var accounts = _accountService.GetAllAccounts();
            var account = accounts.FirstOrDefault(a => a.Id == id);

            var result = BaseResultUtil.Success(account);
            return Ok(result);
        }
        #endregion

        #region POST

        /// <summary>
        /// 简单POST请求
        /// (无请求体数据)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult PostSimple()
        {
            BaseResult<string> result = BaseResultUtil.Success<string>("简单POST请求");

            //这样丢失内容协商,只会返回JSON数据
            return new JsonResult(result);
        }

        /// <summary>
        /// POST 请求
        /// 创建新账号(请求体数据)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult PostCreate([FromBody]Account account)
        {
            //注意:参数加[FromBody]特性,在有服务注入对象时,默认使用服务注入的对象而不是请求体
            CreatedAtActionResult? result = new CreatedAtActionResult("GetAccount","Normal",null,account);

            return Ok(result);
        }

        /// <summary>
        /// POST 请求
        /// 更新账号(请求体数据)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult PostUpdate([FromBody] Account account)
        {
            var result = BaseResultUtil.Success<Account>(account);
            return Ok(result);
        }

        /// <summary>
        /// POST 请求
        /// 删除账号(查询参数)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult PostRemove([FromQuery] int id)
        {
            var account = _accountService.GetAllAccounts().FirstOrDefault(a => a.Id == id);
            var result = BaseResultUtil.Success<Account>(account);
            return Ok(result);
        }
        
        #endregion

        #region DELETE
        /// <summary>
        /// DELETE 请求
        /// 删除账号(查询参数)
        /// </summary>
        /// <returns></returns>
        [HttpDelete]
        public IActionResult Delete([FromQuery] int id)
        {
            var account = _accountService.GetAllAccounts().FirstOrDefault(a => a.Id == id);
            var result = BaseResultUtil.Success(account?.Id);
            return Ok(result);
        }

        /// <summary>
        /// DELETE 请求
        /// 删除数据(JsonBodyData)
        /// </summary>
        /// <returns></returns>
        [HttpDelete]
        public IActionResult DeleteForJsonData([FromBody] Account account)
        {
            var result = BaseResultUtil.Success<Account>(account);
            return Ok(result);
        }
        #endregion

        #region OPTIONS
        /// <summary>
        /// 简单OPTIONS请求
        /// (无请求体数据)
        /// </summary>
        /// <returns></returns>
        [HttpOptions]
        [HttpPost]
        public IActionResult OptionsSimple()
        {
            BaseResult<string> result = BaseResultUtil.Success<string>("简单OPTIONS请求");

            //这样丢失内容协商,只会返回JSON数据
            return Ok(result);
        }
        #endregion

        #region PATCH

        /// <summary>
        /// 部分更新账号
        /// </summary>
        /// <param name="vm">更新账号</param>
        /// <returns></returns>
        [HttpPatch]
        public IActionResult PatchDemo([FromBody]Account vm)
        { 
            var account = _accountService.GetAllAccounts().FirstOrDefault(a => a.Id == vm.Id);

            if (account == null)
            {
                return BadRequest("要更新的账号不存在!");
            }

            //部分更新
            account.Name = vm.Name;

            var result = BaseResultUtil.Success<Account>(account);

            return Ok(result);
        }
        #endregion

        #region TRACE 注意:.NET 不提供直接Trace请求支持,但可以使用单独中间件提供此功能

        /// <summary>
        ///  获取指定账号
        /// </summary>
        /// <param name="accountId">账号Id</param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult TraceDemo(int accountId)
        {
            var account = _accountService.GetAllAccounts().FirstOrDefault(a => a.Id == accountId);

            if (account == null)
            {
                return BadRequest("要更新的账号不存在!");
            }

            return Ok(account);
        }
        #endregion

        #region CONNECT
        #endregion
    }
}