import com.gridnine.xtrip.common.Environment;
import com.gridnine.xtrip.common.l10n.model.LocaleHelper;
import com.gridnine.xtrip.common.model.EntityContainer;
import com.gridnine.xtrip.common.model.EntityReference;
import com.gridnine.xtrip.common.model.booking.BookingFile;
import com.gridnine.xtrip.common.model.booking.BaseProduct;
import com.gridnine.xtrip.common.model.booking.BaseTicketProduct;
import com.gridnine.xtrip.common.model.booking.CommonProductIndex;
import com.gridnine.xtrip.common.model.booking.ProductStatus;
import com.gridnine.xtrip.common.model.booking.ProductIndex;
import com.gridnine.xtrip.common.model.booking.BookingFileIndex;
import com.gridnine.xtrip.common.model.booking.Reservation;
import com.gridnine.xtrip.common.model.booking.Traveller;
import com.gridnine.xtrip.common.model.booking.air.Product;
import com.gridnine.xtrip.common.model.booking.air.ProductFop;
import com.gridnine.xtrip.common.model.booking.air.Segment;
import com.gridnine.xtrip.common.model.booking.air.SegmentTariff;
import com.gridnine.xtrip.common.model.booking.insurance.InsuranceAccident;
import com.gridnine.xtrip.common.model.booking.insurance.InsuranceTouristic;
import com.gridnine.xtrip.common.model.booking.railway.RailwayProduct;
import com.gridnine.xtrip.common.model.booking.Traveller;
import com.gridnine.xtrip.common.model.dict.ClassOfService;
import com.gridnine.xtrip.common.model.entity.EntityStorage;
import com.gridnine.xtrip.common.model.helpers.BookingHelper
import com.gridnine.xtrip.common.model.helpers.CommonReservationGdsNameInfoHelper;
import com.gridnine.xtrip.common.model.helpers.DictHelper;
import com.gridnine.xtrip.common.model.helpers.ProfileHelper;
import com.gridnine.xtrip.common.model.profile.Organization;
import com.gridnine.xtrip.common.model.profile.Person;
import com.gridnine.xtrip.common.reports.model.AgentReportParameters;
import com.gridnine.xtrip.common.reports.model.AllProductsTemplateReportTicket;
import com.gridnine.xtrip.common.search.SearchCriterion;
import com.gridnine.xtrip.common.search.SearchQuery;
import com.gridnine.xtrip.common.util.MiscUtil;
import com.gridnine.xtrip.common.model.helpers.AirProductHelper;
import com.gridnine.xtrip.common.railway.model.helpers.RailwayProductHelper;
import com.gridnine.xtrip.common.model.booking.railway.RailwayProductFop;
import java.text.SimpleDateFormat;
import java.lang.Integer;
import java.util.List;
import java.util.ArrayList;
import java.util.Locale;


//CREATING STYLES
createStyle(name: 'title',fontBold: true, h_span: 10, h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight:20)
createStyle(name: 'metadataTitle',fontBold: true, h_span: 2, h_alignment: 'RIGHT', v_alignment: 'CENTER', fontHeight:10)
createStyle(name: 'metadataValue', parent: 'metadataTitle', h_span: 10, fontBold: false, h_alignment: 'LEFT')
createStyle(name: 'metadataDateValue', parent: 'metadataValue', format: 'm/d/yy')
createStyle(name: 'header',fontBold: false,  h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight:10, leftBorder:'MEDIUM', rightBorder:'MEDIUM', topBorder:'MEDIUM', bottomBorder:'MEDIUM', wrapText: true)
createStyle(name: 'data',fontBold: false,  h_alignment: 'CENTER', v_alignment: 'CENTER', fontHeight:10, leftBorder:'THIN', rightBorder:'THIN', topBorder:'THIN', bottomBorder:'THIN')
createStyle(name: 'textData',parent: 'data')
createStyle(name: 'numberData',parent: 'data',h_alignment: 'RIGHT')
createStyle(name: 'dateData',parent: 'data',h_alignment: 'RIGHT',format: 'm/d/yy')
createStyle(name: 'statusGroupTitle', parent: 'header', h_span: 13, h_alignment: 'RIGHT', fontBold: true)
createStyle(name: 'statusGroupNumber',parent: 'statusGroupTitle',  h_span: 1)
createStyle(name: 'subagencyGroupTitle', parent: 'statusGroupTitle')
createStyle(name: 'subagencyGroupNumber',parent: 'subagencyGroupTitle',  h_span: 1)
createStyle(name: 'totalTitle', parent: 'subagencyGroupTitle')
createStyle(name: 'totalNumber',parent: 'totalTitle', h_span: 1)

class Ticket
{
    ProductStatus productStatus;
    String travellerName;
    String productType;
    String routeLine;
    String reservationNumber;
    String bookingAgentName;
    String ticketNumber;
    boolean refusedInReportPeriod;
}

public boolean isRefusedInReportPeriod(final Date aPeriodBegin, final Date aPeriodEnd,
        final Product prod) {

    for (ProductFop fop : AirProductHelper.getClientContractRelation(prod)
    .getFops()) {

        if (!fop.isRefused() || (fop.getOperationDate() == null)) {
            continue;
        }

        if (!MiscUtil.isBetween(aPeriodBegin(),
        aPeriodEnd(), fop.getOperationDate())) {
            continue;
        }
        return true;
    }
    return false;
}

public boolean isRefusedInReportPeriod(final aPeriodBegin, final Date aPeriodEnd,
        final RailwayProduct prod) {

    for (RailwayProductFop fop : RailwayProductHelper.getClientContractRelation(prod)
    .getFops()) {

        if (!fop.isRefused() || (fop.getOperationDate() == null)) {
            continue;
        }

        if (!MiscUtil.isBetween(aPeriodBegin,
        aPeriodEnd, fop.getOperationDate())) {
            continue;
        }
        return true;
    }
    return false;
}


def periodBeginParameter = parameters['key-report-params']?.periodBegin;
def periodEndParameter = parameters['key-report-params']?.periodEnd;
def corpClientRef = parameters['CLIENT']
def corpClient = corpClientRef.toString()
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");
def productsOnDate = [:]
def aviaCountOnDate = [:]
def railwayCountOnDate = [:]
allTickets.each{CommonProductIndex ticket ->
    Ticket ourTicket = new Ticket();

    def bookingCtr = EntityStorage.get().resolve(ticket.source)
    if(!bookingCtr){
        return;
    }
    BookingFile bookingFile = bookingCtr.entity;
    if(bookingFile.customerProfile.equals(corpClientRef))
    {
        def prod = BookingHelper.findProductByUid(ticket.navigationKey, bookingCtr.entity)
        if(!prod){
            return
        }
        if(prod  != null)
        {
            BaseProduct baseProduct = prod ;
            Reservation reservation = baseProduct.getReservation();
            if (reservation != null) {            
                EntityReference<Person> bookingAgent =
                        reservation.getBookingAgent();
                 
                if (bookingAgent != null) {
                    EntityContainer<Person> bookingAgentCont =
                            EntityStorage.get().resolve(bookingAgent);
                    if (bookingAgentCont != null) {
                        Person person = bookingAgentCont.getEntity();
                        Locale locale = person.getPreferredLocale();
                        if (locale != null) {
                            String fullName = "";
                            String lastName =
                                    person.getLastName().getValues().get(locale);
                            String firstName =
                                    person.getFirstName().getValues().get(locale);
                            if (lastName != null) {
                                fullName = fullName + lastName;
                            }
                            if (firstName != null) {
                                fullName = fullName + firstName;
                            }
                            if (!fullName.isEmpty()) {
                                ourTicket.setBookingAgentName(fullName);
                            }
                        }
                    }
                }
                ourTicket.setReservationNumber(CommonReservationGdsNameInfoHelper
                        .getDisplayedRecordLocator(reservation));
            }
            if(baseProduct instanceof Product)
            {
                Product airProduct = (Product) baseProduct;
                ourTicket.setProductType("авиа")
                Traveller traveller = airProduct.getTraveller();
                if (traveller != null) {
                    String name = traveller.getName();
                    if (name != null) {
                        ourTicket.setTravellerName(name);
                    }
                }
                ourTicket.setProductStatus(((Product) baseProduct).getStatus());
                ourTicket.setRouteLine(AirProductHelper.getRouteLine((Product)baseProduct));
                ourTicket.setTicketNumber(AirProductHelper.getTicketNumber((Product)baseProduct));
                ourTicket.setRefusedInReportPeriod(isRefusedInReportPeriod(periodBeginParameter, periodEndParameter, airProduct));
            }
            else
            {
                return
            }

            String productType = ourTicket.getProductType();
            if(productType.equals("авиа"))
            {
                Integer aviaCount = (Integer)aviaCountOnDate.get(dateFormat.format(ticket.issueDate));
                if(aviaCount != null)
                {
                    aviaCount += 1;
                }
                else
                {
                    aviaCount = 1;
                }
                aviaCountOnDate.put(dateFormat.format(ticket.issueDate), aviaCount)
            }
          
            List<Ticket> ticketList = productsOnDate.get(dateFormat.format(ticket.issueDate));
            if(ticketList == null)
            {

                ticketList = new ArrayList<Ticket>();
                ticketList.add(ourTicket);
            }
            else
            {
                ticketList.add(ourTicket);
            }
            productsOnDate.put(dateFormat.format(ticket.issueDate), ticketList)
        }
    }
}


for(productsEntry in productsOnDate)
{
    def productDate = productsEntry.key.toString();
    List<Ticket> ticketList = productsOnDate.get(productDate);
    if(ticketList == null)
        return;
    //REPORT
    page{productDate}{
        //title
        rowHeight(30)
        text('Отчет о количестве созданных клиентом за день онлайн-услуг', 'title')
        //metadata
        nextRow();
        rowHeight(13);
        text('Дата: ', 'metadataTitle');
        nextColumn(); text(productDate, 'metadataValue');
        nextRow();
        text('Клиент:', 'metadataTitle');
        nextColumn();
        text(corpClient, 'metadataValue');
        nextRow();
        text('Общее кол-во АВИА-услуг:', 'metadataTitle');
        nextColumn();
        if(aviaCountOnDate.get(productDate) == null)
        {
            number(0, 'metadataValue');
        }
        else
        {
            number(aviaCountOnDate?.get(productDate), 'metadataValue');
        }       
        nextRow();
        int scw = 10
        //header
        2.times{nextRow()}
        setStyle('header')
        rowHeight(40)
        columnWidth(2*scw);
        text('Дата');
        nextColumn();columnWidth(scw);text('Тип услуги');
        nextColumn();columnWidth(2.5*scw);text('ФИО путешественника');
        nextColumn();columnWidth(3*scw);text('Маршрут');
        nextColumn();columnWidth(2.5*scw);text('ФИО создавшего заказ');
        nextColumn();columnWidth(scw);text('Номер брони');
        nextColumn();columnWidth(2*scw);text('Номер билета');
        nextColumn();columnWidth(2.5*scw);text('Статус услуги');
        nextColumn();columnWidth(scw);text('Наличие возврата');
        nextColumn();columnWidth(3*scw);text('Комментарии');
        nextRow()
        rowHeight(12)
        for(Ticket ticket : ticketList)
        {

            if(ticket == null)
                return;
            text(productDate, 'textData');
            nextColumn()
            text(ticket?.productType, 'textData');
            nextColumn()
            text(ticket?.travellerName, 'textData');
            nextColumn()
            text(ticket?.routeLine, 'textData');
            nextColumn()
            text(ticket?.bookingAgentName, 'textData');
            nextColumn()
            text(ticket?.reservationNumber, 'textData');
            nextColumn()
            text(ticket?.ticketNumber, 'textData');
            nextColumn()
            def productStatus = " "
            if(ticket?.productStatus.equals(ProductStatus.BOOKING))
            {
                productStatus = "Забронирован"
            }
            else if(ticket?.productStatus.equals(ProductStatus.EXCHANGE))
            {
                productStatus = "Обмен"
            }
            else if(ticket?.productStatus.equals(ProductStatus.REFUND))
            {
                productStatus = "Возврат"
            }
            else if(ticket?.productStatus.equals(ProductStatus.SELL))
            {
                productStatus = "Продажа"
            }
            else if(ticket?.productStatus.equals(ProductStatus.VOID))
            {
                productStatus = "Аннулирован"
            }
            else if(ticket?.productStatus.equals(ProductStatus.VOID_BOOKING))
            {
                productStatus = "Аннулирована бронь"
            }

            text(productStatus, 'textData')
            nextColumn()
            def refusedInReport = " "
            if(ticket?.refusedInReportPeriod)
            {
                refusedInReport = "Да"
            }
            else
            {
                refusedInReport = "Нет"
            }
            text(refusedInReport, 'textData')
            nextColumn()
            text(" ", 'textData');
            nextRow()
        }
    }
}
