import com.gridnine.xtrip.common.model.EntityContainer
import com.gridnine.xtrip.common.model.booking.BaseProduct
import com.gridnine.xtrip.common.model.booking.BookingFile
import com.gridnine.xtrip.common.model.booking.BookingFileIndex
import com.gridnine.xtrip.common.model.booking.GeneralProductContractRelationData
import com.gridnine.xtrip.common.model.booking.GeneralProductFop
import com.gridnine.xtrip.common.model.booking.Reservation
import com.gridnine.xtrip.common.model.booking.air.AirProductContractRelationData
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.misc.UniversalProduct
import com.gridnine.xtrip.common.model.booking.railway.RailwayProduct
import com.gridnine.xtrip.common.model.booking.railway.RailwayProductContractRelationData
import com.gridnine.xtrip.common.model.booking.railway.RailwayProductFop
import com.gridnine.xtrip.common.model.entity.EntityStorage
import com.gridnine.xtrip.common.model.helpers.AirProductHelper
import com.gridnine.xtrip.common.model.helpers.ProfileHelper
import com.gridnine.xtrip.common.model.helpers.UniversalProductHelper
import com.gridnine.xtrip.common.model.system.PaymentType
import com.gridnine.xtrip.common.railway.model.helpers.RailwayProductHelper
import com.gridnine.xtrip.common.search.SearchQuery
import com.gridnine.xtrip.common.search.SearchCriterion.SimpleCriterion

String uid = "4fe12c4e-183b-4add-bd01-a28fc14a5906";

List<PaymentType> preservePaymentTypes = Arrays.asList(
        PaymentType.TICKET, PaymentType.MTD, PaymentType.CREDIT_CARD,
        PaymentType.CREDIT_CARD_TCH, PaymentType.CREDIT);

String code = "5555555";

SearchQuery query = new SearchQuery();

query.getCriteria().getCriterions().add(SimpleCriterion.eq("containerUid", uid));

List<BookingFileIndex> indexes =
        EntityStorage.get().search(BookingFileIndex.class, query).getData();

for (BookingFileIndex index : indexes) {

    EntityContainer<BookingFile> bookingFileContainer =
            EntityStorage.get().resolve(index.getSource());

    if (bookingFileContainer != null) {

        boolean save = false;

        BookingFile bookingFile = bookingFileContainer.getEntity();

        for(Reservation reservation : bookingFile.getReservations()) {

            for(BaseProduct baseProduct : reservation.getProducts()) {

                if (baseProduct instanceof Product) {

                    Product product = (Product) baseProduct;

                    AirProductContractRelationData subagentContractRelation = AirProductHelper
                            .getSubagentContractRelation(product, false);

                    if (subagentContractRelation != null) {

                        for (ProductFop fop : subagentContractRelation.getFops()) {

                            if (!preservePaymentTypes.contains(fop.getType())) {

                                fop.setType(PaymentType.INVOICE);
                                fop.setOperationDate(null);
                                fop.setAgent(null);
                                
                                save = true;
                            }
                        }
                    }

                    if (!ProfileHelper.isOrganizationCode(
                    AirProductHelper.getSubagency(product), code)) {

                        AirProductContractRelationData clientContractRelation =
                                AirProductHelper
                                .getClientContractRelation(product);

                        if (clientContractRelation != null) {

                            for (ProductFop fop : clientContractRelation.getFops()) {

                                if (!preservePaymentTypes.contains(fop.getType())) {

                                    fop.setType(PaymentType.INVOICE);
                                    fop.setOperationDate(null);
                                    fop.setAgent(null);
                                    
                                    save = true;
                                }
                            }
                        }
                    }
                    
                } else if (baseProduct instanceof RailwayProduct) {

                    RailwayProduct product = (RailwayProduct) baseProduct;

                    RailwayProductContractRelationData subagentContractRelation =
                            RailwayProductHelper
                            .getSubagentContractRelation(product, false);

                    if (subagentContractRelation != null) {

                        for (RailwayProductFop fop : subagentContractRelation.getFops()) {

                            if (!preservePaymentTypes.contains(fop.getType())) {

                                fop.setType(PaymentType.INVOICE);
                                fop.setOperationDate(null);
                                fop.setAgent(null);
                                
                                save = true;
                            }
                        }
                    }

                    if (!ProfileHelper.isOrganizationCode(
                    RailwayProductHelper.getSubagency(product), code)) {

                        RailwayProductContractRelationData clientContractRelation =
                                RailwayProductHelper
                                .getClientContractRelation(product);

                        if (clientContractRelation != null) {

                            for (RailwayProductFop fop : clientContractRelation.getFops()) {

                                if (!preservePaymentTypes.contains(fop.getType())) {

                                    fop.setType(PaymentType.INVOICE);
                                    fop.setOperationDate(null);
                                    fop.setAgent(null);

                                    save = true;
                                }
                            }
                        }
                    }
                    
                } else if (baseProduct instanceof UniversalProduct) {

                    UniversalProduct product =
                            (UniversalProduct) baseProduct;

                    GeneralProductContractRelationData subagentContractRelation =
                            UniversalProductHelper
                            .getSubagentContractRelation(product, false);

                    if (subagentContractRelation != null) {

                        for (GeneralProductFop fop : subagentContractRelation.getFops()) {

                            if (!preservePaymentTypes.contains(fop.getType())) {

                                fop.setType(PaymentType.INVOICE);
                                fop.setOperationDate(null);
                                fop.setAgent(null);
                                
                                save = true;
                            }
                        }
                    }

                    if (!ProfileHelper.isOrganizationCode(
                    UniversalProductHelper.getSubagency(product),
                    code)) {

                        GeneralProductContractRelationData clientContractRelation =
                                UniversalProductHelper
                                .getClientContractRelation(product);

                        if (clientContractRelation != null) {

                            for (GeneralProductFop fop : clientContractRelation.getFops()) {

                                if (!preservePaymentTypes.contains(fop.getType())) {

                                    fop.setType(PaymentType.INVOICE);
                                    fop.setOperationDate(null);
                                    fop.setAgent(null);
                                    
                                    save = true;
                                }
                            }
                        }
                    }
                    
                } else {
                    throw new Exception("unsupported product type -> " + baseProduct);
                }
            }
        }
        
        if(save) {
            
            bookingFileContainer.getVersionInfo().setDataSource("fix_booking_files_fops_script");
            
            EntityStorage.get().save(bookingFileContainer, true);
        }
    }
}
