﻿using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.EntityFrameworkCore;

namespace DailyWork
{
    public static class WorkEndpoint
    {
        public static RouteGroupBuilder WorkAPI(this RouteGroupBuilder workGroup)
        {
            workGroup.MapPost("/", CreateWork);
            workGroup.MapGet("/", GetAllWork);
            workGroup.MapGet("/complete", GetCompletedWork);
            workGroup.MapGet("/{id}", GetWorkById);
            workGroup.MapPut("/{id}", UpdateWorkById);
            workGroup.MapPatch("/{id}", UpdateWorkByIdWithPatch);
            workGroup.MapDelete("/{id}", DeleteWorkById);

            return workGroup;
        }

        public static async Task<IResult> CreateWork(Work work, WorkDb db)
        {
            db.Works.Add(work);
            await db.SaveChangesAsync();

            return TypedResults.Created($"/works/{work.Id}", work);
        }

        public static async Task<IResult> GetAllWork(WorkDb db)
        {
            return TypedResults.Ok(await db.Works.ToListAsync());
        }

        public static async Task<IResult> GetCompletedWork(WorkDb db)
        {
            return TypedResults.Ok(await db.Works.Where(t => t.IsComplete).ToListAsync());
        }

        public static async Task<IResult> GetWorkById(int id, WorkDb db)
        {
            return await db.Works.FindAsync(id)
                is Work work
                    ? TypedResults.Ok(work)
                    : TypedResults.NotFound();
        }

        public static async Task<IResult> UpdateWorkById(int id, Work work, WorkDb db)
        {
            var todo = await db.Works.FindAsync(id);

            if (todo is null) return TypedResults.NotFound();

            todo.Name = work.Name;
            todo.TimeStart = work.TimeStart;
            todo.TimeEnd = work.TimeEnd;
            todo.IsComplete = work.IsComplete;

            await db.SaveChangesAsync();

            return TypedResults.NoContent();
        }
        public static async Task<IResult> UpdateWorkByIdWithPatch(int id, WorkDto workDto, WorkDb db)
        {
            var todo = await db.Works.FindAsync(id);

            if (todo is null) return TypedResults.NotFound();

            if (workDto.Name is not null) todo.Name = workDto.Name;
            if (workDto.IsComplete is not null) todo.IsComplete = workDto.IsComplete.Value;
            if (workDto.TimeStart is not null) todo.TimeStart = workDto.TimeStart;
            if (workDto.TimeEnd is not null) todo.TimeEnd = workDto.TimeEnd;

            await db.SaveChangesAsync();

            return TypedResults.NoContent();
        }

        public static async Task<IResult> DeleteWorkById(int id, WorkDb db)
        {
            if (await db.Works.FindAsync(id) is Work work)
            {
                db.Works.Remove(work);
                await db.SaveChangesAsync();
                return TypedResults.NoContent();
            }

            return TypedResults.NotFound();
        }
    }
}
