using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Dapper;
using Siger.Middlelayer.Dapper.ResultData;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Siger.ApiDashboard.Utilities
{
    public class OeeHelper
    {
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly ISigerAndonStationConfigRepository _andonStationConfigRepository;
        private readonly IProductRouteRepository _productRouteRepository;
        private readonly ISigerAndonInfoRepository _andonInfoRepository;
        private readonly ISigerAndonExpectionTypeRepository _andonExpectionTypeRepository;

        public OeeHelper(ISigerProjectMachineRepository machineRepository, ISigerAndonStationConfigRepository andonStationConfigRepository, IProductRouteRepository productRouteRepository,
            ISigerAndonInfoRepository andonInfoRepository, ISigerAndonExpectionTypeRepository andonExpectionTypeRepository)
        {
            _machineRepository = machineRepository;
            _andonStationConfigRepository = andonStationConfigRepository;
            _productRouteRepository = productRouteRepository;
            _andonInfoRepository = andonInfoRepository;
            _andonExpectionTypeRepository = andonExpectionTypeRepository;
        }
        public ResponseOee GetOee(long start, long end, int section, int pid, int cid,IEnumerable<LocationYield> yieldData,int bottleMachine)
        {
            var now = UnixTimeHelper.GetNow();
            if (now >= start && now <= end)
            {
                end = now;
            }
            var dtStart = UnixTimeHelper.ConvertStringDateTime(start.ToStr());
            var dtEnd = UnixTimeHelper.ConvertStringDateTime(end.ToStr());
            //var machines = _machineRepository.GetAttributionMachineIds(section, pid);
            //var botton_machines = _andonStationConfigRepository.GetList(f => f.project_id == pid && f.status != 0 && f.station_type == 1 && machines.Contains(f.machine_id)).Select(s => s.machine_id);
            //var yieldRepository = new LocationYieldRepository(cid, pid);
            //var yieldData = yieldRepository.GetLocationYields(botton_machines, dtStart, dtEnd);
            var molecular = 0d;
            var denominator = 0d;
            var products = yieldData.Select(s => s.productName).Distinct();

            foreach (var product in products)
            {
                var working_hours = _productRouteRepository.GetLastProductRouteByName(pid, product);
                var tempYield = yieldData.Where(f => f.productName == product).Sum(s => s.yield);
                molecular += working_hours * tempYield;
            }
            var restTime = 0d;
            var stopExpection = _andonExpectionTypeRepository.Get(f => f.projectid == pid && f.status != 0 && f.is_caloee == 0 && f.is_passprocess == 1)?.id ?? 0;
            if (stopExpection != 0)
            {
                var andonData = _andonInfoRepository.GetList(f => f.projectid == pid && f.status > (int)AndonState.Approve && f.expection_type == stopExpection && f.create_time >= start && f.create_time <= end && f.machine== bottleMachine).ToList();
                //last data
                var lastData = andonData.FirstOrDefault(f => f.approve_time >= end);
                if (lastData != null)
                {
                    restTime += end - lastData.approve_time;
                }
                //first data
                var firstData = _andonInfoRepository.GetList(f => f.projectid == pid && f.expection_type == stopExpection && f.create_time < start && f.machine==bottleMachine, "create_time").FirstOrDefault();
                if (firstData != null && firstData.complete_time < end && firstData.complete_time > start)
                {
                    andonData.Add(new Middlelayer.TpmRepository.Entities.siger_andon_info { create_time = start, complete_time = firstData.complete_time });
                }
                //sum
                restTime += andonData.Select(s => s.complete_time - s.create_time).Sum();
                //all rest data
                if (firstData != null && firstData.create_time <= start && firstData.complete_time >= end)
                {
                    restTime = end - start;
                }
            }
            denominator = end - start - restTime;
            return new ResponseOee(molecular, denominator);
        }
    }
    public class ResponseOee
    {
        private double molecular;
        private double denominator;
        public ResponseOee(double molecular, double denominator)
        {
            this.molecular = molecular;
            this.denominator = denominator;
        }
        public double Molecular { get => molecular; set => molecular = value; }
        public double Denominator { get => denominator; set => denominator = value; }
        public double Oee
        {
            get
            {
                if (Denominator <= 0)
                {
                    return 0;
                }
                else
                {
                    return Math.Round(Molecular * 100 / Denominator, 2);
                }
            }
        }
    }
}
