using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using RobotNet.MapManager.Data;
using RobotNet.MapManager.Services;
using RobotNet.MapShares.Dtos;
using RobotNet.Shares;
using System.Text.Json;

namespace RobotNet.MapManager.Controllers;

[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ActionsController(MapEditorDbContext MapDb, LoggerController<ActionsController> Logger) : ControllerBase
{
    [HttpPost]
    public async Task<MessageResult<ActionDto>> CreateAction([FromBody] ActionCreateModel model)
    {
        try
        {
            var map = await MapDb.Maps.FindAsync(model.MapId);
            if (map == null) return new(false, $"Không tồn tại map id = {model.MapId}");

            if (MapDb.Actions.Any(action => action.Name == model.Name && action.MapId == model.MapId)) return new(false, $"Tên Action {model.Name} đã tồn tại");

            var entity = await MapDb.Actions.AddAsync(new()
            {
                MapId = model.MapId,
                Name = model.Name,
                Content = model.Content,
            });
            await MapDb.SaveChangesAsync();

            return new(true)
            {
                Data = new()
                {
                    Id = entity.Entity.Id,
                    MapId = entity.Entity.MapId,
                    Name = entity.Entity.Name,
                    Content = entity.Entity.Content,
                }
            };
        }
        catch(Exception ex)
        {
            Logger.Warning($"CreateAction: Hệ thống có lỗi xảy ra - {ex.Message}");
            return new(false, $"CreateAction: Hệ thống có lỗi xảy ra - {ex.Message}");
        }
    }

    [HttpGet]
    [Route("{id}")]
    public async Task<IEnumerable<ActionDto>> GetActions(Guid id)
    {
        return await MapDb.Actions.Where(action => action.MapId == id).Select(action => new ActionDto()
        {
            Id = action.Id,
            MapId = action.MapId,
            Name = action.Name,
            Content = action.Content,
        }).ToListAsync();
    }

    [HttpPut]
    public async Task<MessageResult> UpdateAction([FromBody] ActionDto model)
    {
        try
        {
            var action = await MapDb.Actions.FindAsync(model.Id);
            if (action is not null)
            {
                action.Name = model.Name;
                action.Content = model.Content;
                MapDb.Actions.Update(action);
                await MapDb.SaveChangesAsync();
                return new(true);
            }
            return new(false, $"Hệ thống không tìm thấy Action {model.Name} này");
        }
        catch (Exception ex)
        {
            Logger.Warning($"UpdateAction: Hệ thống có lỗi xảy ra - {ex.Message}");
            return new(false, $"UpdateAction: Hệ thống có lỗi xảy ra - {ex.Message}");
        }
    }

    [HttpDelete]
    [Route("{id}")]
    public async Task<MessageResult> DeleteAction(Guid id)
    {
        try
        {
            var action = await MapDb.Actions.FindAsync(id);
            if (action is not null)
            {
                foreach (var node in MapDb.Nodes)
                {
                    var actionIds = JsonSerializer.Deserialize<Guid[]>(node.Actions);
                    if (actionIds is not null && actionIds.Any(a => a == action.Id))
                    {
                        var acitonIdsAfter = actionIds.ToList();
                        acitonIdsAfter.Remove(action.Id);
                        node.Actions = JsonSerializer.Serialize(acitonIdsAfter.Count > 0 ? acitonIdsAfter : []);
                    }
                }
                foreach (var edge in MapDb.Edges)
                {
                    var actionIds = JsonSerializer.Deserialize<Guid[]>(edge.Actions);
                    if (actionIds is not null && actionIds.Any(a => a == action.Id))
                    {
                        var acitonIdsAfter = actionIds.ToList();
                        acitonIdsAfter.Remove(action.Id);
                        edge.Actions = JsonSerializer.Serialize(acitonIdsAfter.Count > 0 ? acitonIdsAfter : []);
                    }
                }
                MapDb.Actions.Remove(action);
                await MapDb.SaveChangesAsync();
                return new(true) ;
            }
            return new(false, $"Hệ thống không tìm thấy Action {id} này");
        }
        catch (Exception ex)
        {
            Logger.Warning($"DeleteAction {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
            return new(false, $"DeleteAction {id}: Hệ thống có lỗi xảy ra - {ex.Message}");
        }
    }
}
