using Blahblah.FlowerStory.Server.Data;
using Blahblah.FlowerStory.Server.Data.Model;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;

namespace Blahblah.FlowerStory.Server.Controller;

/// <summary>
/// 花草相关服务
/// </summary>
[ApiController]
[Produces("application/json")]
[Route("api/flower")]
public class FlowerController : BaseController
{
    /// <inheritdoc/>
    public FlowerController(FlowerDatabase database, ILogger<BaseController>? logger = null) : base(database, logger)
    {
    }

    /// <summary>
    /// 获取用户名下所有符合条件的花草
    /// </summary>
    /// <remarks>
    /// 请求示例:
    /// 
    ///     GET /api/flower/query
    ///     Authorization: authorization id
    /// 
    /// 参数:
    /// 
    ///     cid: int?
    ///     key: string?
    ///     from: long?
    ///     to: long?
    ///     cfrom: decimal?
    ///     cto: decimal?
    /// 
    /// </remarks>
    /// <param name="categoryId">类别 id</param>
    /// <param name="key">查询关键字</param>
    /// <param name="buyFrom">起始购买日期</param>
    /// <param name="buyTo">结束购买日期</param>
    /// <param name="costFrom">开销最小值</param>
    /// <param name="costTo">开销最大值</param>
    /// <returns>会话有效则返回符合条件的花草集</returns>
    /// <response code="200">返回符合条件的花草集</response>
    /// <response code="401">未找到登录会话或已过期</response>
    /// <response code="403">用户已禁用</response>
    /// <response code="404">未找到关联用户</response>
    [Route("query", Name = "queryFlowers")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [HttpGet]
    public ActionResult<FlowerItem[]> GetFlowers(
        [FromQuery(Name = "cid")] int? categoryId,
        [FromQuery] string? key,
        [FromQuery(Name = "from")] long? buyFrom,
        [FromQuery(Name = "to")] long? buyTo,
        [FromQuery(Name = "cfrom")] decimal? costFrom,
        [FromQuery(Name = "cto")] decimal? costTo)
    {
        var (result, user) = CheckPermission();
        if (result != null)
        {
            return result;
        }
        if (user == null)
        {
            return NotFound();
        }

        SaveDatabase();

        var flowers = database.Flowers.Where(f => f.OwnerId == user.Id);
        if (categoryId != null)
        {
            flowers = flowers.Where(f => f.CategoryId == categoryId);
        }
        if (key != null)
        {
            flowers = flowers.Where(f =>
                f.Name.ToLower().Contains(key.ToLower()) ||
                f.Purchase != null &&
                f.Purchase.ToLower().Contains(key.ToLower()));
        }
        if (buyFrom != null)
        {
            flowers = flowers.Where(f => f.DateBuyUnixTime >= buyFrom);
        }
        if (buyTo != null)
        {
            flowers = flowers.Where(f => f.DateBuyUnixTime <= buyTo);
        }
        if (costFrom != null)
        {
            flowers = flowers.Where(f => f.Cost != null && f.Cost >= costFrom);
        }
        if (costTo != null)
        {
            flowers = flowers.Where(f => f.Cost != null && f.Cost <= costTo);
        }

        return Ok(flowers.ToArray());
    }

    /// <summary>
    /// 移除用户的花草
    /// </summary>
    /// <remarks>
    /// 请求示例:
    /// 
    ///     DELETE /api/flower/remove
    ///     Authorization: authorization id
    /// 
    /// 参数:
    /// 
    ///     id: int
    /// 
    /// </remarks>
    /// <param name="id">花草唯一 id</param>
    /// <returns>会话有效则返回操作影响的数据库行数</returns>
    /// <response code="200">返回操作影响的数据库行数</response>
    /// <response code="401">未找到登录会话或已过期</response>
    /// <response code="403">用户已禁用</response>
    /// <response code="404">未找到关联用户</response>
    [Route("remove", Name = "removeFlower")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [HttpDelete]
    public ActionResult<int> RemoveFlower([FromQuery][Required] int id)
    {
        var (result, user) = CheckPermission();
        if (result != null)
        {
            return result;
        }
        if (user == null)
        {
            return NotFound();
        }

        var count = RemoveUserFlower(user.Id, id);

        SaveDatabase();

        return Ok(count);
    }

    /// <summary>
    /// 批量移除用户的花草
    /// </summary>
    /// <remarks>
    /// 请求示例:
    /// 
    ///     POST /api/flower/remove
    ///     Authorization: authorization id
    ///     [
    ///         2, 4, 5, 11
    ///     ]
    /// 
    /// </remarks>
    /// <param name="ids">要移除的花草唯一 id 的数组</param>
    /// <returns>会话有效则返回操作影响的数据库行数</returns>
    /// <response code="200">返回操作影响的数据库行数</response>
    /// <response code="401">未找到登录会话或已过期</response>
    /// <response code="403">用户已禁用</response>
    /// <response code="404">未找到关联用户</response>
    [Route("removeany", Name = "removeFlowers")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [HttpPost]
    [Consumes("application/json")]
    public ActionResult<int> RemoveFlower([FromBody] int[] ids)
    {
        var (result, user) = CheckPermission();
        if (result != null)
        {
            return result;
        }
        if (user == null)
        {
            return NotFound();
        }

        var count = RemoveUserFlowers(user.Id, ids);

        SaveDatabase();

        return Ok(count);
    }

    /// <summary>
    /// 用户添加花草
    /// </summary>
    /// <remarks>
    /// 请求示例:
    /// 
    ///     POST /api/flower/add
    ///     Authorization: authorization id
    ///     {
    ///         "categoryId": 0,
    ///         "name": "玛格丽特",
    ///         "dateBuy": 1684919954743,
    ///         "cost": 5.00,
    ///         "purchase": "花鸟市场"
    ///     }
    /// 
    /// </remarks>
    /// <param name="flower">花草参数</param>
    /// <returns>添加成功则返回已添加的花草对象</returns>
    /// <response code="200">返回已添加的花草对象</response>
    /// <response code="401">未找到登录会话或已过期</response>
    /// <response code="403">用户已禁用</response>
    /// <response code="404">未找到关联用户</response>
    [Route("add", Name = "addFlower")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [HttpPost]
    [Consumes("application/json")]
    public ActionResult<FlowerItem> AddFlower([FromBody] FlowerParameter flower)
    {
        var (result, user) = CheckPermission();
        if (result != null)
        {
            return result;
        }
        if (user == null)
        {
            return NotFound();
        }

        var item = new FlowerItem
        {
            OwnerId = user.Id,
            CategoryId = flower.CategoryId,
            Name = flower.Name,
            DateBuyUnixTime = flower.DateBuy,
            Cost = flower.Cost,
            Purchase = flower.Purchase
        };
        database.Flowers.Add(item);
        SaveDatabase();

        return Ok(item);
    }

    /// <summary>
    /// 修改花草
    /// </summary>
    /// <remarks>
    /// 请求示例:
    /// 
    ///     PUT /api/flower/update
    ///     Authorization: authorization id
    ///     {
    ///         "id": 0,
    ///         "categoryId": 1,
    ///         "name": "姬小菊",
    ///         "dateBuy": 1684935276117,
    ///         "cost": 15.00,
    ///         "purchase": null
    ///     }
    /// 
    /// </remarks>
    /// <param name="update">修改参数</param>
    /// <returns>修改成功则返回已修改的花草对象</returns>
    /// <response code="200">返回已修改的花草对象</response>
    /// <response code="401">未找到登录会话或已过期</response>
    /// <response code="403">用户已禁用</response>
    /// <response code="404">未找到关联用户或者未找到将修改的花草对象</response>
    [Route("update", Name = "updateFlower")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status403Forbidden)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [HttpPut]
    [Consumes("application/json")]
    public ActionResult<FlowerItem> Update([FromBody] FlowerUpdateParameter update)
    {
        var (result, user) = CheckPermission();
        if (result != null)
        {
            return result;
        }
        if (user == null)
        {
            return NotFound();
        }

        var flower = database.Flowers.SingleOrDefault(f => f.Id == update.Id && f.OwnerId == user.Id);
        if (flower == null)
        {
            return NotFound(update.Id);
        }
        flower.CategoryId = update.CategoryId;
        flower.Name = update.Name;
        flower.DateBuyUnixTime = update.DateBuy;
        flower.Cost = update.Cost;
        flower.Purchase = update.Purchase;
        SaveDatabase();

        return Ok(user);
    }
}