using System.Diagnostics;
using FastBlog.Core.Abstractions.Repositories.Blogs;
using FastBlog.Core.Models.Blogs;
using FastBlog.Core.Services;
using FastBlog.Web.Models;
using Microsoft.AspNetCore.Mvc;

namespace FastBlog.Web.Controllers;

[Route("")]
[Route("blogs")]
public class BlogsController(BlogService service) : Controller
{
    [HttpGet]
    [Route("{*slug}")]
    public async Task<IActionResult> Index(string? slug)
    {
        if (string.IsNullOrWhiteSpace(slug))
            slug = null;

        var blog = await service.Get(slug);

        if (blog is null)
            return NotFound();

        return View(blog);
    }

    [HttpGet]
    [Route("")]
    public async Task<IActionResult> Index()
    {
        var blog = await service.Get(null);

        if (blog is null)
            return NotFound();

        return View(blog);
    }

    [HttpGet]
    [Route("edit/{id:int?}")]
    public async ValueTask<IActionResult> Edit(int? id)
    {
        if (!id.HasValue)
        {
            var date = DateTime.UtcNow;
            return View(
                new EditBlog
                {
                        Text = "# My new blog",
                        Title = "Blog from " + DateTime.UtcNow.ToString("g"),
                        SourceLocation = $"{date:yyyy-MM-dd-HH-mm}_blog.md",
                        CreatedAt = date,
                        ModifiedAt = date,
                        FullWidth = false,
                        ShowDetails = true,
                        Slug = "blog-" + date.ToString("yyyy-MM-dd-HH-mm"),
                        Visible = false
                }
            );
        }
        
        var blog = await service.GetForEdit(id.Value);
        
        if (blog is null)
            return NotFound();

        return View(new EditBlog
        {
            Id = blog.Metadata.Id,
            Text = blog.Text,
            Title = blog.Metadata.Title,
            SourceLocation = blog.Metadata.SourceLocation,
            CreatedAt = blog.Metadata.CreatedAt,
            ModifiedAt = blog.Metadata.ModifiedAt,
            FullWidth = blog.Metadata.FullWidth,
            ShowDetails = blog.Metadata.ShowDetails,
            Slug = blog.Metadata.Slug,
            Visible = blog.Metadata.Visible,
            ImageUrl = blog.Metadata.ImageUrl,
            Signature = blog.Metadata.Signature
        });
    }

    [HttpPost]
    [Route("edit")]
    public async Task<IActionResult> Edit([FromForm] EditBlog editBlog)
    {
        var result = await service.Update(new()
        {
            Text = editBlog.Text,
            Metadata = new()
            {
                Id = editBlog.Id,
                Title = editBlog.Title,
                Slug = editBlog.Slug,
                ShowDetails = editBlog.ShowDetailsStr is not null,
                ImageUrl = editBlog.ImageUrl,
                CreatedAt = editBlog.CreatedAt,
                ModifiedAt = editBlog.ModifiedAt,
                Signature = editBlog.Signature,
                FullWidth = editBlog.FullWidthStr is not null,
                Visible = editBlog.VisibleStr is not null,
                SourceLocation = editBlog.SourceLocation
            }
        });

        if (result.IsError)
        {
            return result.AsError.ShortCode switch
            {
                "already_exists" => Conflict(),
                "not_found" => NotFound(),
                _ => throw result.AsError
            };
        }

        return Redirect($"/blogs/{editBlog.Slug}");
    }
    
    [HttpPost]
    [Route("preview")]
    public IActionResult Preview([FromForm] EditBlog editBlog)
    {
        return View("Preview", new Blog
        {
            Text = editBlog.Text,
            Metadata = new()
            {
                Title = editBlog.Title,
                Slug = editBlog.Slug,
                ShowDetails = editBlog.ShowDetailsStr is not null,
                ImageUrl = editBlog.ImageUrl,
                CreatedAt = editBlog.CreatedAt,
                ModifiedAt = editBlog.ModifiedAt,
                Signature = editBlog.Signature,
                FullWidth = editBlog.FullWidthStr is not null,
                Visible = editBlog.VisibleStr is not null,
                SourceLocation = editBlog.SourceLocation
            }
        });
    }
    
    [HttpDelete]
    [Route("{id:int}")]
    public async Task<IActionResult> Delete(int id)
    {
        var result = await service.Delete(id);
        
        if (!result)
            return NotFound();
        
        HttpContext.Response.Headers.Append("Hx-Redirect", "/");
        return Ok();
    }
}