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

namespace Blahblah.FlowerStory.Server.Controller;

/// <summary>
/// 图片相关服务
/// </summary>
[Route("photo")]
public class ImageController(FlowerDatabase database, ILogger<ImageController>? logger = null) : BaseController<ImageController>(database, logger)
{
    static byte[]? emptyAvatar;

    static byte[] EmptyAvatar => emptyAvatar ??= GetEmbeddedData("image.avatar.jpg");

    /// <summary>
    /// 请求自己的头像
    /// </summary>
    /// <remarks>
    /// 请求示例:
    /// 
    ///     GET /photo/my_avatar
    ///     Authorization: authorization id
    /// 
    /// </remarks>
    /// <returns>认证通过则显示自己的头像</returns>
    /// <response code="200">返回头像</response>
    /// <response code="401">认证失败</response>
    [Route("my_avatar", Name = "getMyAvatar")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [HttpGet]
    public ActionResult GetMyAvatar()
    {
        var (result, token) = CheckToken();
        if (result != null)
        {
            return result;
        }
        if (token == null)
        {
            return Unauthorized();
        }
        var avatar = QueryUserAvatar(token.UserId);
        if (avatar?.Length > 0)
        {
            return File(avatar, "image/jpeg");
        }
        return File(EmptyAvatar, "image/jpeg");
    }

    /// <summary>
    /// 请求用户头像
    /// </summary>
    /// <remarks>
    /// 请求示例:
    /// 
    ///     GET /photo/avatar/2.jpg
    /// 
    /// </remarks>
    /// <param name="uid">用户唯一 id</param>
    /// <returns>认证通过则显示用户头像</returns>
    /// <response code="200">返回头像</response>
    /// <response code="401">认证失败</response>
    [Route("avatar/{uid}.jpg", Name = "getAvatar")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [HttpGet]
    public ActionResult GetAvatar([Required] int uid)
    {
        //var (result, token) = CheckToken();
        //if (result != null)
        //{
        //    return result;
        //}
        //if (token == null)
        //{
        //    return Unauthorized();
        //}
        var avatar = QueryUserAvatar(uid);
        if (avatar?.Length > 0)
        {
            return File(avatar, "image/jpeg");
        }
        return File(EmptyAvatar, "image/jpeg");
    }

    /// <summary>
    /// 请求花草照片
    /// </summary>
    /// <remarks>
    /// 请求示例:
    /// 
    ///     GET /photo/flower/1/test.jpg
    /// 
    /// </remarks>
    /// <param name="fid">花草唯一 id</param>
    /// <param name="name">照片名称</param>
    /// <param name="thumb">是否为缩略图</param>
    /// <returns>认证通过则显示花草照片</returns>
    /// <response code="200">返回花草照片</response>
    /// <response code="401">认证失败</response>
    /// <response code="404">未找到花草照片</response>
    [Route("flower/{fid}/{name}", Name = "getFlowerPhoto")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [HttpGet]
    public async Task<ActionResult> GetFlowerPhoto([Required] int fid, [Required] string name, [FromQuery] string? thumb = null)
    {
        //var (result, token) = CheckToken();
        //if (result != null)
        //{
        //    return result;
        //}
        //if (token == null)
        //{
        //    return Unauthorized();
        //}

#if PRODUCTION
        var referrer = Request.Headers.Referer.ToString();
        if (string.IsNullOrEmpty(referrer))
        {
            return BadRequest();
        }
        if (!referrer.StartsWith("https://app.tsanie.org"))
        {
            return Forbid();
        }
#endif
        var filename = WebUtility.UrlEncode(name);
        var directory = Path.Combine(Program.DataPath, "uploads", fid.ToString());
        var original = Path.Combine(directory, filename);
        var thumbnail = Path.Combine(directory, $"{filename}.thumb");
        if (!string.IsNullOrEmpty(thumb))
        {
            if (System.IO.File.Exists(thumbnail))
            {
                var thumbnailData = await System.IO.File.ReadAllBytesAsync(thumbnail);
                return File(thumbnailData, "image/jpeg");
            }
            else if (System.IO.File.Exists(original))
            {
                try
                {
                    var originalData = await System.IO.File.ReadAllBytesAsync(original);
                    var thumbnailData = CreateThumbnail(originalData);
                    await System.IO.File.WriteAllBytesAsync(thumbnail, thumbnailData);
                    return File(thumbnailData, "image/jpeg");
                }
                catch (Exception ex)
                {
                    logger?.LogWarning(ex, "failed to create thumbnail for flower: {fid}, name: {name}, error: {message}", fid, name, ex.Message);
                }
            }
            return NotFound();
        }
        if (System.IO.File.Exists(original))
        {
            var data = await System.IO.File.ReadAllBytesAsync(original);
            return Path.GetExtension(original).ToLower() switch
            {
                ".png" => File(data, "image/png"),
                _ => File(data, "image/jpeg"),
            };
        }
        return NotFound();
    }
}