// Copyright (C) 2021-present sam (starshines.gay)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

using System.Net;
using Catalogger.Backend.Api.Middleware;
using Microsoft.AspNetCore.Mvc;
using Remora.Discord.API.Abstractions.Objects;

namespace Catalogger.Backend.Api;

public partial class GuildsController
{
    [HttpPost("redirects")]
    public async Task<IActionResult> CreateRedirectAsync(
        string id,
        [FromBody] CreateRedirectRequest req
    )
    {
        var (guildId, _) = await ParseGuildAsync(id);
        var guildChannels = channelCache.GuildChannels(guildId).ToList();
        var guildConfig = await guildRepository.GetAsync(guildId);

        Console.WriteLine($"Source: {req.Source}, target: {req.Target}");

        var source = guildChannels.FirstOrDefault(c =>
            c.ID.Value == req.Source
            && c.Type
                is ChannelType.GuildText
                    or ChannelType.GuildCategory
                    or ChannelType.GuildAnnouncement
                    or ChannelType.GuildForum
                    or ChannelType.GuildMedia
                    or ChannelType.GuildVoice
        );
        if (source == null)
            throw new ApiError(
                HttpStatusCode.BadRequest,
                ErrorCode.BadRequest,
                "Unknown source channel ID or it's not a valid source"
            );
        var target = guildChannels.FirstOrDefault(c =>
            c.ID.Value == req.Target && c.Type is ChannelType.GuildText
        );
        if (target == null)
            throw new ApiError(
                HttpStatusCode.BadRequest,
                ErrorCode.BadRequest,
                "Unknown target channel ID or it's not a valid target"
            );

        guildConfig.Channels.Redirects[source.ID.Value] = target.ID.Value;
        await guildRepository.UpdateConfigAsync(guildId, guildConfig);

        return NoContent();
    }

    [HttpDelete("redirects/{channelId}")]
    public async Task<IActionResult> DeleteRedirectAsync(string id, ulong channelId)
    {
        var (guildId, _) = await ParseGuildAsync(id);
        var guildConfig = await guildRepository.GetAsync(guildId);

        if (!guildConfig.Channels.Redirects.ContainsKey(channelId))
            throw new ApiError(
                HttpStatusCode.BadRequest,
                ErrorCode.BadRequest,
                "That channel is already not being redirected"
            );

        guildConfig.Channels.Redirects.Remove(channelId, out _);
        await guildRepository.UpdateConfigAsync(guildId, guildConfig);

        return NoContent();
    }

    public record CreateRedirectRequest(ulong Source, ulong Target);
}
