using Microsoft.Extensions.Logging;
using RealEstateTransactions.Repositories;

namespace RealEstateTransactions.Reports
{
    public class TableReport
    {
        private readonly IDealRepository _dealRepository;

        private readonly IPreSalesServicesRepository _preSalesServicesRepository;

        private readonly ILogger<TableReport> _logger;

        internal static readonly string[] item = ["Сделка", "Дата", "Доход от сделки", "Доход от допродажных услуг"];

        public TableReport(IDealRepository dealRepository,
        IPreSalesServicesRepository preSalesServicesRepository, ILogger<TableReport> logger)
        {
            _dealRepository = dealRepository ?? throw new
            ArgumentNullException(nameof(dealRepository));
            _preSalesServicesRepository = preSalesServicesRepository ?? throw new
            ArgumentNullException(nameof(preSalesServicesRepository));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        public bool CreateTable(string filePath, int apartmentId, DateTime startDate,
        DateTime endDate)
        {
            try
            {
                new ExcelBuilder(filePath)
                .AddHeader("Сводка по доходу от продажи квартиры", 0, 4)
                .AddParagraph("за период", 0)
                .AddTable([10, 10, 10, 15], GetData(apartmentId, startDate,
                endDate))
                .Build();
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при формировании документа");
                return false;
            }
        }

        private List<string[]> GetData(int apartmentId, DateTime startDate, DateTime
        endDate)
        {
            var data = _dealRepository
            .ReadDeals()
            .Where(x => x.Deal_date >= startDate && x.Deal_date <= endDate && 
            x.Apartment_ID == apartmentId)
            .Select(x => new {
                DealId = (int?)x.Id, Date = (DateTime?)x.Deal_date, DealPrice = (float?)x.Deal_price, ServicesPrice = (float?)null
            })
            .Union(
            _preSalesServicesRepository
            .ReadPreSalesServices()
            .Where(x => x.Apartment_ID == apartmentId)
            .Select(x => new {
                DealId = (int?)null, Date = (DateTime?)null, DealPrice = (float?)null, ServicesPrice = (float?)x.Cost
            }))
            .OrderBy(x => x.Date);

            return
            new List<string[]>() { item }
            .Union(
            data
            .Select(x => new string[] {
                x.DealId?.ToString() ?? string.Empty, x.Date?.ToString() ?? string.Empty, 
                x.DealPrice?.ToString() ?? string.Empty, x.ServicesPrice?.ToString() ?? string.Empty}))
            .Union(
            [["Всего", "", data.Sum(x => x.DealPrice ?? 0).ToString(),
            data.Sum(x => x.ServicesPrice ?? 0).ToString()]])
            .ToList();
        }
    }
}