using Electricity.Api.Models;
using Microsoft.EntityFrameworkCore;

namespace Electricity.Api.Services;

public class ElectricityService
{
    private readonly DatabaseContext databaseContext;

    public ElectricityService(DatabaseContext databaseContext)
    {
        this.databaseContext = databaseContext;
    }

    public async Task<Minute[]> GetDetailsFor(string date)
    {
        return (await databaseContext.ElectricityLogs
            .Where(l => l.Date == date)
            .OrderBy(l => l.TimeUtc)
            .ToArrayAsync())
            .Select(Minute.FromEntity)
            .ToArray();
    }

    public async Task<Day[]> GetSummariesFor(string from, string to)
    {
        var list = new List<Day>();
        var current = DateOnly.ParseExact(from, Constants.isoDateFormat);
        var limit = DateOnly.ParseExact(to, Constants.isoDateFormat);
        do
        {
            list.Add(await GetSummaryFor(current));
            current = current.AddDays(1);
        } while (current <= limit);

        return list.ToArray();
    }

    private async Task<Day> GetSummaryFor(DateOnly date)
    {
        var databaseDate = date.ToString(Constants.isoDateFormat);
        var baseQuery = databaseContext.ElectricityLogs
            .Where(l => l.Date == databaseDate)
            .OrderBy(l => l.TimeUtc);
        var first = await baseQuery.FirstOrDefaultAsync();
        if (first == null)
        {
            return Day.Empty(date);
        }
        var last = await baseQuery.LastAsync();

        var firstAsModel = Day.FromEntity(first);
        if (last.TimeUtc == first.TimeUtc)
        {
            return Day.Empty(date);
        }

        var lastAsModel = Day.FromEntity(last);
        return new Day(
            lastAsModel.Date,
            lastAsModel.TotalPowerUse - firstAsModel.TotalPowerUse,
            lastAsModel.TotalPowerReturn - firstAsModel.TotalPowerReturn,
            lastAsModel.TotalGasUse - firstAsModel.TotalGasUse
        );
    }
}