package com.fractalite.hermes.teldar.parsers;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Currency;
import java.util.Date;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;

import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.InvalidPayloadException;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;

import com.fractalite.hermes.teldar.cfg.ContentProvider;
import com.fractalite.hermes.teldar.tools.ObjectToXml;
import com.fractalite.models.commerce.OrderStatus;
import com.fractalite.models.commerce.PriceScope;
import com.fractalite.models.commerce.Quote;
import com.fractalite.models.commerce.QuoteTemplate;
import com.fractalite.models.commerce.RequestForQuote;
import com.fractalite.models.commerce.TermOfSale;
import com.fractalite.models.common.Address;
import com.fractalite.models.common.CodeNamePair;
import com.fractalite.models.common.Company;
import com.fractalite.models.common.Location;
import com.fractalite.models.common.Money;
import com.fractalite.models.travel.PaxType;
import com.fractalite.models.travel.Traveller;
import com.fractalite.models.travel.Trip;
import com.fractalite.models.travel.stay.BedLayout;
import com.fractalite.models.travel.stay.Hotel;
import com.fractalite.models.travel.stay.HotelStay;
import com.fractalite.models.travel.stay.Occupancy2;
import com.fractalite.models.travel.stay.Room;
import com.fractalite.models.travel.stay.RoomProduct;
import com.fractalite.models.travel.stay.RoomType;
import com.fractalite.models.travel.stay.StayItem2;
import com.gekko_holding.webservice.v2_4.AvailabilityResponse;
import com.gekko_holding.webservice.v2_4.CancellationFeesPolicy;
import com.gekko_holding.webservice.v2_4.Facility;
import com.gekko_holding.webservice.v2_4.HotelAvailabilityResponse;
import com.gekko_holding.webservice.v2_4.HotelResponse;
import com.gekko_holding.webservice.v2_4.Offer;
import com.gekko_holding.webservice.v2_4.RoomOffer;


public class ParserQuotesresponse extends TeldarParsers {
	protected static Logger logger = LoggerFactory.getLogger(ParserQuotesresponse.class);
	private CamelContext camelContext;

	@Override
	public void process(Exchange exchange) throws InvalidPayloadException, ParserConfigurationException, SAXException,
			IOException, XPathExpressionException {

		logger.trace("Invoking TELDAR ParseTeldarQuotesResponse Processor.......");
		RequestForQuote requestForQuote = new RequestForQuote();
		HotelAvailabilityResponse resp = exchange.getIn().getMandatoryBody(HotelAvailabilityResponse.class);
		requestForQuote = getHotelQuotes(resp.getAvailResponse(), exchange);
		exchange.getIn().setBody(requestForQuote, RequestForQuote.class);
		exchange.getIn().setHeader("HermesPartnerId", "teldar");
		logger.info("End TELDAR ParseHotelQuotesResponse Processor......." + ObjectToXml.printXML(requestForQuote));
	}

	private RequestForQuote getHotelQuotes(AvailabilityResponse teldarHotel, Exchange exchange)
			throws XPathExpressionException {

		QuoteTemplate quoteTemplate = exchange.getProperty("hermesquery", QuoteTemplate.class);
		LocalDate checkin = quoteTemplate.getTrip().getContent(HotelStay.class).get(0).getCheckin();
		LocalDate checkout = quoteTemplate.getTrip().getContent(HotelStay.class).get(0).getCheckout();
		RequestForQuote requestForQuote = new RequestForQuote(quoteTemplate);

		if (teldarHotel != null && teldarHotel.getHotelResponse() != null && !teldarHotel.getHotelResponse().isEmpty()) {
			 logger.info(" \n 12teldarHotel" + teldarHotel + "̣ size " +teldarHotel.getHotelResponse().size());
			for (HotelResponse respHotel : teldarHotel.getHotelResponse()) {

				Hotel hermesHotel = new Hotel();
				hermesHotel.addMeta("source", ContentProvider.PROVIDER_ID);

				if (respHotel.getCode() != null) {
					hermesHotel.setCode(respHotel.getCode());
				}
				// Hotel Chain
				if (respHotel.getChainCode() != null) {
					hermesHotel.setChain(new Company(respHotel.getChainCode()));
				}
				if (respHotel.getName() != null) {
					hermesHotel.setName(respHotel.getName());
				}

				com.fractalite.models.common.Address hermesAddress = new Address(respHotel.getAddress(), "",
						new Location(respHotel.getCity().getCode().substring(2, 5),
								respHotel.getCity().getCode().substring(2, 5)),
						new Location(respHotel.getCity().getCode().substring(0, 2),
								respHotel.getCity().getCode().substring(0, 2)));
				hermesHotel.setAddress(hermesAddress);

				// lattitude
				if (respHotel.getLatitude() != null) {
					hermesHotel.setLatitude(respHotel.getLatitude().floatValue());
				}
				// longitude
				if (respHotel.getLongitude() != null) {
					hermesHotel.setLongitude(respHotel.getLongitude().floatValue());
				}
				// Hotel Rating
				if (respHotel.getRating() != null) {
					HotelRating rating;
					if (respHotel.getRating().getCode().equals("UNKNOWN")
							|| respHotel.getRating().getCode().equals("UNRATED")) {
						rating = HotelRating.valueOf(respHotel.getRating().getCode());
					} else {
						rating = HotelRating.valueOf("_" + respHotel.getRating().getCode());
					}
					if (rating != null) {
						hermesHotel.setRating(new CodeNamePair(String.valueOf(rating.value()), rating.value() + "ST"));
					}
				}
				// distance to ---> meta
				if (respHotel.getDistance() > 0) {
					hermesHotel.getMetas().put("distance", Arrays.asList(String.valueOf(respHotel.getDistance())));
				}

				// price---> room
				if (respHotel.getOffers() != null && respHotel.getOffers().getOffer() != null
						&& !respHotel.getOffers().getOffer().isEmpty()) {
					List<String> offres = new ArrayList<String>();

				}
				/* Setting facilities. e.g: Accès Internet, etc. */
				if (respHotel.getFacilities() != null && respHotel.getFacilities().getFacilities() != null
						&& !respHotel.getFacilities().getFacilities().isEmpty()) {
					/*
					 * list of all facilities content[e.g: Accès Internet] not code[e.g : SVGEKKO-1]
					 */
					List<String> facilities = new ArrayList<String>();
					for (Facility respFacility : respHotel.getFacilities().getFacilities()) {
						if (respFacility.getCode() != null && !respFacility.getCode().isEmpty()) {
							com.fractalite.hermes.teldar.parsers.Facility hermesFacility = com.fractalite.hermes.teldar.parsers.Facility
									.valueOf(respFacility.getCode().replace("-", "_"));
							if (hermesFacility != null) {
								facilities.add(hermesFacility.getValue());
							}
						}
					}
					hermesHotel.setAmenities(facilities);
				}

				DateTimeFormatter dateParser = DateTimeFormat.forPattern("yyyyMMdd");
				// LocalDate checkin =
				// dateParser.parseDateTime(hermesHotel.getCheckin()).toLocalDate();
			
				Currency currency = Currency.getInstance("EUR");

				// RoomProduct roomProduct = null;
				// Offer offe=new Offer();

				List<RoomType> hermesRoomTypes = new ArrayList<RoomType>();
				if (respHotel.getOffers() != null && respHotel.getOffers().getOffer() != null) {
					 logger.info("I try to create Product ");
					for (Offer offer : respHotel.getOffers().getOffer()) {

						for (RoomOffer roomOffer : offer.getRoomOffers().getRoomOffer()) {
							List<Room> requestRooms = new ArrayList<Room>();

							RoomProduct roomProduct = new RoomProduct();

							Trip trip = new Trip();
							BedLayout bedLayout = null;

							List<Traveller> trs = new ArrayList<Traveller>();

							Quote quote = new Quote(Currency.getInstance("EUR"));
							Room room = null;
							RoomType hermesRoomType = null;

							for (int ad = 0; ad < roomOffer.getAdultsCount(); ad++) {
								trs.add(new Traveller(PaxType.ADULT));

							}
						    int travellerCount=0;
							List<Integer> childrenAges = new ArrayList<Integer>();
							for (int ch = 0; ch < roomOffer.getChildrenCount(); ch++) {
								Traveller traveller = new Traveller(PaxType.CHILD, Byte.parseByte("10"));
								traveller.setId(Integer.toString(++travellerCount));
								traveller.setClassification(PaxType.INFANT);

								trs.add(traveller);
								//childrenAges.add(5);

							}

							CodeNamePair board = null;
							// if (roomOffer.getBoardType() != null && roomOffer.getBoardType().getCode() !=
							// null
							// && roomOffer.getBoardType().getValue() != null)
							if (roomOffer != null) {
								if (roomOffer.getRoomType() != null && roomOffer.getRoomType().getCode() != null
										&& roomOffer.getRoomType().getValue() != null
										&& roomOffer.getAdultsCount() > 0) {
									board = new CodeNamePair(roomOffer.getBoardType().getCode(),
											roomOffer.getBoardType().getValue());

									int occup = roomOffer.getAdultsCount() + roomOffer.getChildrenCount();

									hermesRoomType = new RoomType(roomOffer.getRoomType().getCode(),
											roomOffer.getRoomType().getValue(), "", "");
									roomProduct = new RoomProduct(offer.getOfferCode(), hermesRoomType, occup, board);

									roomProduct.setOccupancy2(new Occupancy2());
									roomProduct.getOccupancy2().setAdults(roomOffer.getAdultsCount());

									roomProduct.getOccupancy2().setChildAge(childrenAges);
									/*
									 * hermesRoomType = new RoomType(roomOffer.getRoomType().getCode(),
									 * roomOffer.getAdultsCount(), roomOffer.getChildrenCount(),
									 * roomOffer.getRoomType().getValue());
									 */
									// hermesRoomTypes.add(hermesRoomType);

									room = new Room(hermesRoomType, board, bedLayout, trs);

									logger.info("adultOffers" + roomOffer.getAdultsCount());

									// hermesRoomType = new RoomType(room.getCode(),occup, occup, room.getName());

									bedLayout = new BedLayout("db", "Double", Byte
											.parseByte("" + roomOffer.getAdultsCount() + roomOffer.getChildrenCount()));

								}

								//logger.info("adulttt" + roomOffer.getAdultsCount());
								//logger.info("childdd" + roomOffer.getChildrenCount()); offer.getOfferCode()
								logger.info("producttttt" + roomOffer.getAdultsCount() + roomOffer.getChildrenCount());
								if (offer.getOfferCode() != null) {
									if (roomOffer.getBoardType() != null && roomOffer.getBoardType().getCode() != null
											&& roomOffer.getBoardType().getValue() != null) {
										roomProduct = new RoomProduct(offer.getOfferCode(), hermesRoomType,
												roomOffer.getAdultsCount() + roomOffer.getChildrenCount(),
												new CodeNamePair(roomOffer.getBoardType().getCode(),
														roomOffer.getBoardType().getValue()));

									}
								}

							}
							// int nbtravellers= roomOffer.getAdultsCount() + roomOffer.getChildrenCount();
							// roomProduct.setCode(String.valueOf(offer.getTaxes()));
							Money totalPrice = new Money(roomOffer.getRoomPrice().getValue(),
									Currency.getInstance(roomOffer.getRoomPrice().getCurrency()));
							roomProduct.setPrice(PriceScope.PURCHASE_UNIT, totalPrice);

							quote.setTrip(quoteTemplate.getTrip());
							quote.addMeta("source", ContentProvider.PROVIDER_ID);

							List<TermOfSale> termsOfSales = new ArrayList<TermOfSale>();
							int ii = 0;
							if (offer.getCancellationFeesPolicy() != null
									&& offer.getCancellationFeesPolicy().size() > 0)
								for (CancellationFeesPolicy cancellation : offer.getCancellationFeesPolicy()) {

									TermOfSale term = new TermOfSale("condition",
											"From " + cancellation.getFromDate() + " to " + cancellation.getToDate()
													+ " price " + cancellation.getPrice() + cancellation.getCurrency());
									try {

										Date date3 = new SimpleDateFormat("dd/MM/yyyy")
												.parse(cancellation.getFromDate());
										 logger.info("hh2hhhhh" +date3.toString());

										java.util.Date d = new SimpleDateFormat("yyyy-MM-dd").parse(checkin.toString());
										// logger.info("psss" +d.toString());

										Long difference = d.getTime() - date3.getTime();
										// logger.info("p2sss" +difference);

										// float daysBetween = (difference / (1000*60*60*24));
										float daysBetween1 = (difference / (86400000));
										int q = (int) daysBetween1;
										// logger.info("p1sss" +daysBetween);

										// Days q=Days.daysBetween((ReadablePartial) date2,(ReadablePartial) date1);
										// logger.info("hh2hhhhh" +q.toString());

										// if(cancellation.getPrice()!= null && cancellation.getPrice().isEmpty()) {

										term.addCharge(q, new Money(Double.parseDouble(cancellation.getPrice()),
												currency.getInstance(cancellation.getCurrency())));

									}

									catch (NumberFormatException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									} catch (Exception e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}

									// term.getCharges().
									termsOfSales.add(term);

								}
							else {
								TermOfSale term = new TermOfSale("condition", "non refundable");
								termsOfSales.add(term);

							}
							roomProduct.setTermsOfSales(termsOfSales);

							int numberOfRooms = 1;
							requestRooms.add(room);
							StayItem2 lineItem = new StayItem2(roomProduct, 1, null, requestRooms,checkin, checkout,offer.getOfferCode());

							lineItem.setStatus(OrderStatus.QUOTE);

							lineItem.addRoom(room);
							lineItem.setPeriod(checkin, checkout);
							lineItem.setQuantity(1);
							quote.getPricing().addItem(lineItem);

							requestForQuote.getQuotes().add(quote);
						}

						// break;
					}
				}

				// break;

				// quote.getPricing().

				// requestForQuote.getQuotes().add(quote );
			}
		}
		
		return requestForQuote;
	}
}