using Dapper;
using Microsoft.Extensions.Logging;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure.Models;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Performance.Services
{
    public class GraphQLService : IAutoInjection
    {
        private readonly ILogger logger;
        private readonly PerforPeremployeeRepository peremployeeRepository;
        private readonly PerforRepreportRepository repreportRepository;
        private readonly PerforReportperformanceRepository reportperformanceRepository;

        public GraphQLService(
            ILogger<GraphQLService> logger,
            PerforPeremployeeRepository peremployeeRepository,
            PerforRepreportRepository repreportRepository,
            PerforReportperformanceRepository reportperformanceRepository
            )
        {
            this.logger = logger;
            this.peremployeeRepository = peremployeeRepository;
            this.repreportRepository = repreportRepository;
            this.reportperformanceRepository = reportperformanceRepository;
        }

        public List<ReportData> GetReportsInfo()
        {
            var reports = repreportRepository.GetEntities(t => t.Sort < 5000);
            if (reports == null || !reports.Any()) return new List<ReportData>();

            var result = new List<ReportData>();
            foreach (var item in reports.OrderBy(t => t.Sort))
            {
                result.Add(new ReportData(item));
            }
            return result;
        }

        public ReportData GetReport(int reportId)
        {
            if (reportId == 0) return new ReportData(new rep_report());
            var report = repreportRepository.GetEntity(t => t.ID == reportId) ?? new rep_report();
            return new ReportData(report);
        }

        public List<ChartData> GetChartData(int reportId, DynamicParameters parameters)
        {
            if (reportId == 0) return new List<ChartData>();

            try
            {
                var report = repreportRepository.GetEntity(t => t.ID == reportId);
                if (report == null || string.IsNullOrEmpty(report.Content)) return new List<ChartData>();

                var sql = report.Content.ToLower();
                string where = GetQueryCondition(sql, parameters);
                sql = sql.Replace("{wh}", where);

                var chartData = repreportRepository.DapperQuery<ChartData>(sql, parameters, 60 * 5);

                return chartData != null && chartData.Any() ? chartData.ToList() : new List<ChartData>();
            }
            catch (Exception ex)
            {
                logger.LogError("GetChartData获取报表数据异常: " + ex.ToString());
                return new List<ChartData>();
            }
        }

        public List<ReportTable> GetReportPerformance(int reportId, DynamicParameters parameters)
        {
            if (reportId == 0) return new List<ReportTable>();

            try
            {
                var report = repreportRepository.GetEntity(t => t.ID == reportId);
                if (report == null || string.IsNullOrEmpty(report.Content)) return new List<ReportTable>();

                var sql = report.Content.ToLower();
                string where = GetQueryCondition(sql, parameters);
                sql = sql.Replace("{wh}", where);

                var chartData = repreportRepository.DapperQuery<ReportTable>(sql, parameters, 60 * 5);

                return chartData != null && chartData.Any() ? chartData.ToList() : new List<ReportTable>();
            }
            catch (Exception ex)
            {
                logger.LogError("GetReportPerformance获取报表数据异常: " + ex.ToString());
                return new List<ReportTable>();
            }
        }

        private string GetQueryCondition(string sql, DynamicParameters parameters)
        {
            StringBuilder builder = new StringBuilder();
            if (parameters != null && parameters.ParameterNames.Any())
            {
                foreach (var parameter in parameters.ParameterNames.Select(t => t))
                {
                    string key = "@" + parameter;
                    if (sql.IndexOf(key) == -1)
                    {
                        builder.Append($" and {parameter} = {key} ");
                    }
                }
            }
            return builder.ToString();
        }
    }
}
