using AsbCloudApp.Data.DailyReport;
using ClosedXML.Excel;

namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
{

    internal class SaubBlock : BlockAbstract
    {
        private readonly SaubDto blockDto;
        private readonly HeadBlock headBlock;
        public CellAddress AddressRotorDrilling { get; }
        public CellAddress AddressSlideDrilling { get; }
        public CellAddress AddressDrillingTableTitle { get; }
        public CellAddress[] AddressDrillingTableHead { get; }
        public CellAddress[] AddressDrillingTableData { get; }
        public CellAddress AddressSlideTableTitle { get; }
        public CellAddress[] AddressSlideTableHead { get; }
        public CellAddress[] AddressSlideTableData { get; }
        public CellAddress AddressTotalTableMechanicalSpeed { get; }
        public CellAddress AddressTotalTableTitle { get; }
        public CellAddress[] AddressTotalTableHead { get; }
        public CellAddress[] AddressTotalTableData { get; }
        public CellAddress IncreaseSpeedSection { get; }
        public CellAddress IncreaseSpeedDay { get; }
        public CellAddress ReductionTimeDrilling { get; }
        public CellAddress RotorSlidePercent { get; }
        public CellAddress MspSection { get; }
        public CellAddress SectionDrillingTimeTotal { get; }
        public CellAddress SectionPenetrationTotal { get; }
        public CellAddress AddressExtensionsCount { get; }
        public CellAddress DeviationFromTVD { get; }
        public CellAddress DeclinesReasonsROP { get; }
        public CellAddress IncreaseSpeedSectionValue { get; }
        public CellAddress IncreaseSpeedDayValue { get; }
        public CellAddress ReductionTimeDrillingValue { get; }
        public CellAddress RotorSlidePercentValue { get; }
        public CellAddress MspSectionValue { get; }
        public CellAddress SectionDrillingTimeTotalValue { get; }
        public CellAddress SectionPenetrationTotalValue { get; }
        public CellAddress AddressExtensionsCountValue { get; }
        public CellAddress DeviationFromTVDValue { get; }
        public override CellAddress AddressBlockBegin { get; }        
        public override CellAddress AddressBlockEnd { get; }

        public SaubBlock(CellAddress addressBlockBegin, SaubDto blockDto, HeadBlock headBlock)
        {
            this.headBlock = headBlock;
            AddressBlockBegin = addressBlockBegin.Copy();
            this.blockDto = blockDto;
            AddressRotorDrilling = addressBlockBegin + (1, 0);
            AddressSlideDrilling = addressBlockBegin + (2, 0);
            AddressDrillingTableTitle = addressBlockBegin + (4, 0);
            AddressDrillingTableHead = new CellAddress[4];
            AddressDrillingTableHead[0] = addressBlockBegin + (5, 0);
            AddressDrillingTableHead[1] = addressBlockBegin + (5, 2);
            AddressDrillingTableHead[2] = addressBlockBegin + (5, 4);
            AddressDrillingTableHead[3] = addressBlockBegin + (5, 6);
            AddressDrillingTableData = new CellAddress[4];
            AddressDrillingTableData[0] = addressBlockBegin + (6, 0);
            AddressDrillingTableData[1] = addressBlockBegin + (6, 2);
            AddressDrillingTableData[2] = addressBlockBegin + (6, 4);
            AddressDrillingTableData[3] = addressBlockBegin + (6, 6);
            AddressSlideTableTitle = addressBlockBegin + (8, 0);
            AddressSlideTableHead = new CellAddress[4];
            AddressSlideTableHead[0] = addressBlockBegin + (9, 0);
            AddressSlideTableHead[1] = addressBlockBegin + (9, 2);
            AddressSlideTableHead[2] = addressBlockBegin + (9, 4);
            AddressSlideTableHead[3] = addressBlockBegin + (9, 6);
            AddressSlideTableData = new CellAddress[4];
            AddressSlideTableData[0] = addressBlockBegin + (10, 0);
            AddressSlideTableData[1] = addressBlockBegin + (10, 2);
            AddressSlideTableData[2] = addressBlockBegin + (10, 4);
            AddressSlideTableData[3] = addressBlockBegin + (10, 6);
            AddressTotalTableTitle = addressBlockBegin + (12, 0);
            AddressTotalTableMechanicalSpeed = addressBlockBegin + (12, 6);
            AddressTotalTableHead = new CellAddress[4];
            AddressTotalTableHead[0] = addressBlockBegin + (13, 0);
            AddressTotalTableHead[1] = addressBlockBegin + (13, 2);
            AddressTotalTableHead[2] = addressBlockBegin + (13, 4);            
            AddressTotalTableData = new CellAddress[4];
            AddressTotalTableData[0] = addressBlockBegin + (14, 0);
            AddressTotalTableData[1] = addressBlockBegin + (14, 2);
            AddressTotalTableData[2] = addressBlockBegin + (14, 4);
            AddressTotalTableData[3] = addressBlockBegin + (14, 6);
            IncreaseSpeedSection = addressBlockBegin + (16, 0);
            IncreaseSpeedSectionValue = addressBlockBegin + (16, 4);
            IncreaseSpeedDay = addressBlockBegin + (17, 0);
            IncreaseSpeedDayValue = addressBlockBegin + (17, 4);
            ReductionTimeDrilling = addressBlockBegin + (18, 0);
            ReductionTimeDrillingValue = addressBlockBegin + (18, 4);
            RotorSlidePercent = addressBlockBegin + (19, 0);
            RotorSlidePercentValue = addressBlockBegin + (19, 4);
            MspSection = addressBlockBegin + (20, 0);
            MspSectionValue = addressBlockBegin + (20, 4);
            SectionDrillingTimeTotal = addressBlockBegin + (21, 0);
            SectionDrillingTimeTotalValue = addressBlockBegin + (21, 4);
            SectionPenetrationTotal = addressBlockBegin + (22, 0);
            SectionPenetrationTotalValue = addressBlockBegin + (22, 4);
            AddressExtensionsCount = addressBlockBegin + (23, 0);
            AddressExtensionsCountValue = addressBlockBegin + (23, 4);
            DeviationFromTVD = addressBlockBegin + (24, 0);
            DeviationFromTVDValue = addressBlockBegin + (24, 4);
            DeclinesReasonsROP = addressBlockBegin + (25, 0);
            AddressBlockEnd = DeclinesReasonsROP + (1,7) ;
        }

        private string FormulaMechanicalSpeed(CellAddress cellSinking, CellAddress cellWatch )
        {
            return string.Format("=IF({0}>0,{1}/{2},0)", cellWatch.ToString(), cellSinking.ToString(), cellWatch.ToString());
        }

        private string FormulaSinking(CellAddress sinkingDrilling, CellAddress sinkingSlide, CellAddress slaughterEnd, CellAddress slaughterBegin)
        {
            return string.Format("=IF(({0}+{1})<>({2}-{3}),\"ОШИБКА\",({0}+{1}))", sinkingSlide.ToString(), sinkingDrilling.ToString(),
                slaughterEnd.ToString(), slaughterBegin.ToString());
        }
        private string FormulaWatch(CellAddress cellSinkingDrill, CellAddress cellSinkingSlide)
        {
            return string.Format("={0}+{1}",
                cellSinkingDrill.ToString(), cellSinkingSlide.ToString());
        }

        public override void Draw(IXLWorksheet sheet)
        {
            sheet._Range(AddressRotorDrilling, AddressRotorDrilling + (0, 7))
                 ._SetValue($"Бурение в роторе :  {blockDto.RotorDrillingModes}");
            sheet._Range(AddressSlideDrilling, AddressSlideDrilling + (0, 7))
                 ._SetValue($"Бурение в слайде :  {blockDto.SlideDrillingModes}");
            sheet._Range(AddressDrillingTableTitle, AddressDrillingTableTitle + (0, 7))
                 ._SetValue("Бурение в роторе(за отчетный период) с использование САУБ - 1");
            sheet._Range(AddressDrillingTableHead[0], AddressDrillingTableHead[0] + (0, 1))
                 ._SetValue("Проходка");
            sheet._Range(AddressDrillingTableHead[1], AddressDrillingTableHead[1] + (0, 1))
                 ._SetValue("Часы бурения");
            sheet._Range(AddressDrillingTableHead[2], AddressDrillingTableHead[2] + (0, 1))
                 ._SetValue("Мех. скорость");
            sheet._Range(AddressDrillingTableHead[3], AddressDrillingTableHead[3] + (0, 1))
                 ._SetValue("Среднее диф. Давление");
            sheet._Range(AddressDrillingTableData[0], AddressDrillingTableData[0] + (0, 1))
                 ._SetValue($"{blockDto.PenetrationInRotor}");
            sheet._Range(AddressDrillingTableData[1], AddressDrillingTableData[1] + (0, 1))
                 ._SetValue($"{blockDto.NumberDrillingHours}");
            sheet._Range(AddressDrillingTableData[2], AddressDrillingTableData[2] + (0, 1))._SetValue("");
            sheet.Cell(AddressDrillingTableData[2])
                .SetFormulaA1(FormulaMechanicalSpeed(AddressDrillingTableData[0], AddressDrillingTableData[1])).Style.SetAllBorders();            
            sheet._Range(AddressDrillingTableData[3], AddressDrillingTableData[3] + (0, 1))
                 ._SetValue($"{blockDto.AVGDiffDropRotor}");
            sheet._Range(AddressSlideTableTitle, AddressSlideTableTitle + (0, 7))
                 ._SetValue("Бурение в слайде (за отчетный период) с использование САУБ-1");
            sheet._Range(AddressSlideTableHead[0], AddressSlideTableHead[0] + (0, 1))
                 ._SetValue("Проходка");
            sheet._Range(AddressSlideTableHead[1], AddressSlideTableHead[1] + (0, 1))
                 ._SetValue("Часы бурения");
            sheet._Range(AddressSlideTableHead[2], AddressSlideTableHead[2] + (0, 1))
                 ._SetValue("Мех. скорость");
            sheet._Range(AddressSlideTableHead[3], AddressSlideTableHead[3] + (0, 1))
                 ._SetValue("Среднее диф. Давление");
            sheet._Range(AddressSlideTableData[0], AddressSlideTableData[0] + (0, 1))
                 ._SetValue($"{blockDto.PenetrationInSlide}");
            sheet._Range(AddressSlideTableData[1], AddressSlideTableData[1] + (0, 1))
                 ._SetValue($"{blockDto.DrillingTimeInRotor}");
            sheet._Range(AddressSlideTableData[2], AddressSlideTableData[2] + (0, 1))._SetValue("");
            sheet.Cell(AddressSlideTableData[2])
                .SetFormulaA1(FormulaMechanicalSpeed(AddressSlideTableData[0], AddressSlideTableData[1])).Style.SetAllBorders();            
            sheet._Range(AddressSlideTableData[3], AddressSlideTableData[3] + (0, 1))
                 ._SetValue($"{blockDto.AVGDiffPressureSlide}");
            sheet._Range(AddressTotalTableTitle, AddressTotalTableTitle + (0, 5))
                 ._SetValue("Итого за отчетный период, использование САУБ-1");
            sheet._Range(AddressTotalTableMechanicalSpeed, AddressTotalTableMechanicalSpeed + (1, 1))
                 ._SetValue("Плановая мех скорость");
            sheet._Range(AddressTotalTableHead[0], AddressTotalTableHead[0] + (0, 1))
                 ._SetValue("Проходка");
            sheet._Range(AddressTotalTableHead[1], AddressTotalTableHead[1] + (0, 1))
                 ._SetValue("Часы бурения");
            sheet._Range(AddressTotalTableHead[2], AddressTotalTableHead[2] + (0, 1))
                 ._SetValue("Мех. скорость");
            
            sheet._Range(AddressTotalTableData[0], AddressTotalTableData[0] + (0, 1))._SetValue("");
            sheet.Cell(AddressTotalTableData[0])
                .SetFormulaA1(FormulaSinking(AddressDrillingTableData[0], AddressSlideTableData[0], headBlock.AddressPeriodTableDataArray[3], headBlock.AddressPeriodTableDataArray[2]));
            sheet._Range(AddressTotalTableData[1], AddressTotalTableData[1] + (0, 1))._SetValue("");
            sheet.Cell(AddressTotalTableData[1])
                .SetFormulaA1(FormulaWatch(AddressDrillingTableData[1], AddressSlideTableData[1]));            
            sheet._Range(AddressTotalTableData[2], AddressTotalTableData[2] + (0, 1))
                 ._SetValue("");
            sheet._Range(AddressTotalTableData[3], AddressTotalTableData[3] + (0, 1))
                 ._SetValue($"{blockDto.SectionROPPlan}");
            sheet._Range(IncreaseSpeedSection, IncreaseSpeedSection + (0, 3))
                 ._SetValue("Увеличение мех скорости за секцию %");
            sheet._Range(IncreaseSpeedSectionValue, IncreaseSpeedSectionValue + (0, 3))
                 ._SetValue($"{blockDto.IncreaseSpeedSection}");
            sheet._Range(IncreaseSpeedDay, IncreaseSpeedDay + (0, 3))
                 ._SetValue("Увеличение мех скорости за сутки %");
            sheet._Range(IncreaseSpeedDayValue, IncreaseSpeedDayValue + (0, 3))
                 ._SetValue($"{blockDto.IncreaseSpeedDay}");
            sheet._Range(ReductionTimeDrilling, ReductionTimeDrilling + (0, 3))
                 ._SetValue("Сокращение времени бурения за секцию, ч");
            sheet._Range(ReductionTimeDrillingValue, ReductionTimeDrillingValue + (0, 3))
                 ._SetValue($"{blockDto.ReductionTimeDrilling}");
            sheet._Range(RotorSlidePercent, RotorSlidePercent + (0, 3))
                 ._SetValue("Ротор / слайд, %");
            sheet._Range(RotorSlidePercentValue, RotorSlidePercentValue + (0, 3))
                 ._SetValue($"{blockDto.RotorSlidePercent}");
            sheet._Range(MspSection, MspSection + (0, 3))
                 ._SetValue("МСП за секцию м/ч.");
            sheet._Range(MspSectionValue, MspSectionValue + (0, 3))
                 ._SetValue($"{blockDto.MspSection}");
            sheet._Range(SectionDrillingTimeTotal, SectionDrillingTimeTotal + (0, 3))
                 ._SetValue("Время бурения за секцию");
            sheet._Range(SectionDrillingTimeTotalValue, SectionDrillingTimeTotalValue + (0, 3))
                 ._SetValue($"{blockDto.SectionDrillingTimeTotal}");
            sheet._Range(SectionPenetrationTotal, SectionPenetrationTotal + (0, 3))
                 ._SetValue("Проходка за секцию");
            sheet._Range(SectionPenetrationTotalValue, SectionPenetrationTotalValue + (0, 3))
                 ._SetValue($"{blockDto.SectionPenetrationTotal}");
            sheet._Range(AddressExtensionsCount, AddressExtensionsCount + (0, 3))
                 ._SetValue("Кол- во наращиваний");
            sheet._Range(AddressExtensionsCountValue, AddressExtensionsCountValue + (0, 3))
                 ._SetValue($"{blockDto.ExtensionsCount}");
            sheet._Range(DeviationFromTVD, DeviationFromTVD + (0, 3))
                 ._SetValue("Отклонение от ГГД +/-, сут");
            sheet._Range(DeviationFromTVDValue, DeviationFromTVDValue + (0, 3))
                 ._SetValue($"{blockDto.DeviationFromTVD}");
            sheet._Range(DeclinesReasonsROP, DeclinesReasonsROP + (1, 7))
                 ._SetValue($"Примечание: {blockDto.DeclinesReasonsROP}");
        }
    }

}