package com.mx.dla.dda.contrato.transaccion.terminos.bos;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mx.dla.dda.contrato.fees.daos.FeesContratoDAO;
import com.mx.dla.dda.contrato.transaccion.terminos.daos.TerminosTransaccionDAO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.FsPeriodoDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.MinimoTipos;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.PeriodoTipos;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.RevenueBoxGloDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.RevenueSeccionDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.RevenueTipos;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.TerminoMinimoDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.TerminosAuxiliarDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.TerminosPaisDTO;
import com.mx.dla.dda.contrato.transaccion.terminos.dtos.TerminosRevenueDTO;
import com.mx.dla.dda.general.utilerias.ListaUtilerias;
import com.mx.dla.global.bos.BaseBO;

@Service
public class TerminosRevenue extends BaseBO {

	@Autowired
	private TerminosTransaccionDAO dao;
	@Autowired
	private FeesContratoDAO feesDao;
	@Autowired
	private TerminosMinimos minimo;

	public RevenueSeccionDTO obtenerRevenue(Long idContrato, String seccion, String[][] release) {
		List<TerminosRevenueDTO> revenues = dao.obtenerRevenueRelease(idContrato, seccion);
		List<String> periodos = dao.obtenerPeriodosRevenue(idContrato, seccion);

		String[] releases = new String[release.length];
		for (int i = 0; i < release.length; i++)
			releases[i] = release[i][2];

		RevenueSeccionDTO revenue = this.procesoRevenue(idContrato, releases, revenues, periodos);

		return revenue;
	}

	public RevenueBoxGloDTO obtenerRevenueMovies(Long idContrato, String seccion, String[][] precio) {
		RevenueBoxGloDTO rev = new RevenueBoxGloDTO();
		Long idSeccion = dao.obtenerIdSeccion(idContrato, seccion);
		List<TerminosRevenueDTO> revenues = dao.obtenerRevenueMoviesBox(idContrato);
		List<String> periodos = dao.obtenerPeriodosRevenueMoviesBox(idContrato, idSeccion);
		Set<String> tiersRaw = new HashSet<String>();

		String tipoRevenue = obtenerTipoRevenue(idContrato, seccion);

		if (RevenueTipos.GLOBAL.equals(RevenueTipos.getSeccion(tipoRevenue))) {
			rev.setRevenueBox(false);
			rev.setRevenueGlobal(true);
		} else {
			rev.setRevenueBox(true);
			rev.setRevenueGlobal(false);
		}

		for (String[] row : precio)
			tiersRaw.add(row[0]);
		String[] tiers = tiersRaw.toArray(new String[tiersRaw.size()]);

		RevenueSeccionDTO revenueBox = this.procesoRevenue(idContrato, tiers, revenues, periodos);
		rev.setDatosRevenueBox(revenueBox.getRevenue());
		rev.setPeriodos(revenueBox.getPeriodos());

		List<TerminosRevenueDTO> revenueGlobal = dao.obtenerRevenueMoviesGlobal(idContrato, seccion);
		String[][] global = this.proceseoRevenueGlobal(revenueGlobal);
		rev.setDatosRevenueGlobal(global);

		return rev;
	}

	public RevenueBoxGloDTO obtenerRevenueSeries(Long idContrato, String seccion, String[][] precio) {
		RevenueBoxGloDTO rev = new RevenueBoxGloDTO();
		Long idSeccion = dao.obtenerIdSeccion(idContrato, seccion);
		List<TerminosRevenueDTO> revenues = dao.obtenerRevenueSeriesBox(idContrato);
		List<String> periodos = dao.obtenerPeriodosRevenueMoviesBox(idContrato, idSeccion);
		Set<String> tiersRaw = new HashSet<String>();

		String tipoRevenue = obtenerTipoRevenue(idContrato, seccion);

		if (RevenueTipos.GLOBAL.equals(RevenueTipos.getSeccion(tipoRevenue))) {
			rev.setRevenueBox(false);
			rev.setRevenueGlobal(true);
		} else {
			rev.setRevenueBox(true);
			rev.setRevenueGlobal(false);
		}

		for (String[] row : precio)
			tiersRaw.add(row[0]);
		String[] tiers = tiersRaw.toArray(new String[tiersRaw.size()]);

		RevenueSeccionDTO revenueBox = this.procesoRevenue(idContrato, tiers, revenues, periodos);

		rev.setDatosRevenueBox(revenueBox.getRevenue());
		rev.setPeriodos(revenueBox.getPeriodos());

		List<TerminosRevenueDTO> revenueGlobal = dao.obtenerRevenueMoviesGlobal(idContrato, seccion);

		String[][] global = this.proceseoRevenueGlobal(revenueGlobal);
		rev.setDatosRevenueGlobal(global);

		return rev;
	}

	public RevenueSeccionDTO procesoRevenue(Long idContrato, String[] release, List<TerminosRevenueDTO> revenues,
			List<String> periodos) {
		RevenueSeccionDTO revenue = new RevenueSeccionDTO();

		if (release == null || release.length == 0)
			release[0] = "";

		if (periodos == null || periodos.isEmpty())
			periodos = Arrays.asList(feesDao.fechaInicio(idContrato) + "-" + feesDao.fechaFin(idContrato));

		String datos[][] = new String[release.length][(periodos.size() * 2) + 1];
		int indFilaPais = 0;

		for (int i = 0; i < release.length; i++) {
			datos[indFilaPais][0] = release[i];
			for (int j = 0; j < periodos.size(); j++) {
				for (int k = 0; k < revenues.size(); k++) {

					TerminosRevenueDTO item = revenues.get(k);
					String fechaInicio = periodos.get(j).split("-")[0];
					if (item.getRelease().equals(release[i]) && fechaInicio.equals(item.getFechaInicio())) {
						datos[indFilaPais][(j * 2) + 1] = item.getDdaPto();
						datos[indFilaPais][(j * 2) + 2] = item.getEstudioPto();
						break;
					}

				}
			}
			indFilaPais++;
		}

		String[] per = new String[periodos.size()];
		per = periodos.toArray(per);

		revenue.setPeriodos(per);
		revenue.setRevenue(datos);
		return revenue;
	}

	public String[][] proceseoRevenueGlobal(List<TerminosRevenueDTO> revenueGlobal) {
		String[][] global = new String[1][3];

		if (revenueGlobal != null && !revenueGlobal.isEmpty()) {
			global = new String[revenueGlobal.size()][3];

			for (int i = 0; i < revenueGlobal.size(); i++) {
				global[i][0] = revenueGlobal.get(i).getFechaInicio() + "-" + revenueGlobal.get(i).getFechaFin();
				global[i][1] = revenueGlobal.get(i).getDdaPto();
				global[i][2] = revenueGlobal.get(i).getEstudioPto();
			}
		}
		return global;
	}

	public void guardarRevenue(Long idContrato, String seccion, Long[] release, RevenueSeccionDTO revenue) {

		if (revenue != null) {
			Long idSeccion = dao.obtenerIdSeccion(idContrato, seccion);
			dao.actualizaTipoRevenue(idSeccion, RevenueTipos.CATEGORIA.getDesc());
			List<FsPeriodoDTO> pers = new ArrayList<FsPeriodoDTO>();
			List<TerminosRevenueDTO> revenues = new ArrayList<TerminosRevenueDTO>();

			for (int i = 0; i < revenue.getPeriodos().length; i++) {
				String periodosRev[] = revenue.getPeriodos()[i].split("-");
				FsPeriodoDTO periodo = new FsPeriodoDTO();
				periodo.setFechaInicio(periodosRev[0]);
				periodo.setFechaFin(periodosRev[1]);
				periodo.setIdSeccion(idSeccion);
				periodo.setIdContrato(idContrato);
				periodo.setTipo("REVENUE");
				dao.guardarPeridoMinimos(periodo);
				pers.add(periodo);
			}

			for (int i = 0; i < revenue.getRevenue().length; i++) {
				for (int j = 0; j < pers.size(); j++) {
					TerminosRevenueDTO t = new TerminosRevenueDTO();
					t.setIdPeriodo(pers.get(j).getIdPeriodo());
					t.setIdRelease(release[i]);
					t.setDdaPto(revenue.getRevenue()[i][(j * 2) + 1]);
					t.setEstudioPto(revenue.getRevenue()[i][(j * 2) + 2]);
					revenues.add(t);
				}
			}
			dao.guardarRevenue(revenues);
		}
	}

	public void guardarRevenueMovies(Long idContrato, String seccion, List<TerminosPaisDTO> categorias,
			RevenueBoxGloDTO revenue) {
		Long idSeccion = dao.obtenerIdSeccion(idContrato, seccion);

		if (revenue.isRevenueGlobal()) {

			List<TerminosRevenueDTO> revenues = new ArrayList<TerminosRevenueDTO>();

			for (int i = 0; i < revenue.getDatosRevenueGlobal().length; i++) {
				TerminosRevenueDTO t = new TerminosRevenueDTO();

				String fechas[] = revenue.getDatosRevenueGlobal()[i][0].split("-");
				t.setFechaInicio(fechas[0]);
				t.setFechaFin(fechas[1]);
				t.setDdaPto(revenue.getDatosRevenueGlobal()[i][1]);
				t.setEstudioPto(revenue.getDatosRevenueGlobal()[i][2]);
				revenues.add(t);
			}
			dao.actualizaTipoRevenue(idSeccion, RevenueTipos.GLOBAL.getDesc());
			dao.guardarValoresRevGlobal(idContrato, idSeccion, revenues);
		} else {
			List<FsPeriodoDTO> pers = new ArrayList<FsPeriodoDTO>();
			List<TerminosRevenueDTO> revenues = new ArrayList<TerminosRevenueDTO>();

			for (int i = 0; i < revenue.getPeriodos().length; i++) {
				String periodosRev[] = revenue.getPeriodos()[i].split("-");
				FsPeriodoDTO periodo = new FsPeriodoDTO();
				periodo.setFechaInicio(periodosRev[0]);
				periodo.setFechaFin(periodosRev[1]);
				periodo.setIdSeccion(idSeccion);
				periodo.setIdContrato(idContrato);
				periodo.setTipo("REVENUE");
				dao.guardarPeridoMinimos(periodo);
				pers.add(periodo);
			}

			for (int i = 0; i < revenue.getDatosRevenueBox().length; i++) {
				for (int j = 0; j < pers.size(); j++) {
					TerminosRevenueDTO t = new TerminosRevenueDTO();
					t.setIdPeriodo(pers.get(j).getIdPeriodo());

					for (TerminosPaisDTO categoria : categorias)
						if (revenue.getDatosRevenueBox()[i][0].equals(categoria.getDescripcion()))
							t.setIdRelease(categoria.getIdPais());

					t.setDdaPto(revenue.getDatosRevenueBox()[i][(j * 2) + 1]);
					t.setEstudioPto(revenue.getDatosRevenueBox()[i][(j * 2) + 2]);
					revenues.add(t);
				}
			}
			dao.actualizaTipoRevenue(idSeccion, RevenueTipos.CATEGORIA.getDesc()); // RevenueTipos.BOX_OFFICE
			dao.guardarValoresRevBoxMovies(idContrato, revenues);
		}
	}

	public void guardarRevenueSeries(Long idContrato, String seccion, List<TerminosPaisDTO> categorias,
			RevenueBoxGloDTO revenue) {
		Long idSeccion = dao.obtenerIdSeccion(idContrato, seccion);
		if (revenue.isRevenueGlobal()) {

			List<TerminosRevenueDTO> revenues = new ArrayList<TerminosRevenueDTO>();

			for (int i = 0; i < revenue.getDatosRevenueGlobal().length; i++) {
				TerminosRevenueDTO t = new TerminosRevenueDTO();

				String fechas[] = revenue.getDatosRevenueGlobal()[i][0].split("-");
				t.setFechaInicio(fechas[0]);
				t.setFechaFin(fechas[1]);
				t.setDdaPto(revenue.getDatosRevenueGlobal()[i][1]);
				t.setEstudioPto(revenue.getDatosRevenueGlobal()[i][2]);
				revenues.add(t);
			}
			dao.actualizaTipoRevenue(idSeccion, RevenueTipos.GLOBAL.getDesc());
			dao.guardarValoresRevGlobal(idContrato, idSeccion, revenues);
		} else {

			List<FsPeriodoDTO> pers = new ArrayList<FsPeriodoDTO>();
			List<TerminosRevenueDTO> revenues = new ArrayList<TerminosRevenueDTO>();

			for (int i = 0; i < revenue.getPeriodos().length; i++) {
				String periodosRev[] = revenue.getPeriodos()[i].split("-");
				FsPeriodoDTO periodo = new FsPeriodoDTO();
				periodo.setFechaInicio(periodosRev[0]);
				periodo.setFechaFin(periodosRev[1]);
				periodo.setIdSeccion(idSeccion);
				periodo.setIdContrato(idContrato);
				periodo.setTipo("REVENUE");
				dao.guardarPeridoMinimos(periodo);
				pers.add(periodo);
			}

			for (int i = 0; i < revenue.getDatosRevenueBox().length; i++) {
				for (int j = 0; j < pers.size(); j++) {
					TerminosRevenueDTO t = new TerminosRevenueDTO();
					t.setIdPeriodo(pers.get(j).getIdPeriodo());

					for (TerminosPaisDTO categoria : categorias)
						if (revenue.getDatosRevenueBox()[i][0].equals(categoria.getDescripcion()))
							t.setIdRelease(categoria.getIdPais());

					t.setDdaPto(revenue.getDatosRevenueBox()[i][(j * 2) + 1]);
					t.setEstudioPto(revenue.getDatosRevenueBox()[i][(j * 2) + 2]);
					revenues.add(t);
				}
			}

			dao.actualizaTipoRevenue(idSeccion, RevenueTipos.CATEGORIA.getDesc()); // RevenueTipos.BOX_OFFICE
			dao.guardarValoresRevBoxSeries(idContrato, revenues);
		}
	}

	public void eliminarRevenue(Long idContrato, String seccion) {
		dao.eliminarRevenue(idContrato, seccion);

	}

	public void elimnarRevenueGlobal(Long idContrato, String seccion) {
		Long idSeccion = dao.obtenerIdSeccion(idContrato, seccion);
		dao.eliminarRevenueGlobalMovies(idContrato, idSeccion);
	}

	public void eliminarRevenueBoxMovies(Long idContrato) {
		dao.eliminarRevenueBoxMovies(idContrato);
	}

	public void eliminarRevenueBoxSeries(Long idContrato) {
		dao.eliminarRevenueBoxSeries(idContrato);
	}

	public RevenueBoxGloDTO obtenerRevenueLibreria(Long idContrato, String seccion) {
		List<TerminosAuxiliarDTO> revenues = dao.obtenerBoxOfficeRevenueDatos(idContrato, seccion,
				PeriodoTipos.REVENUE.getDesc());
		List<TerminoMinimoDTO> minimos = dao.obtenerMinimosCategoriasBoxOffice(idContrato, seccion);
		List<TerminosAuxiliarDTO> periodosAuxiliar = dao.obtenerPeriodos(idContrato, seccion,
				PeriodoTipos.REVENUE.getDesc());
		List<String> periodos = new ArrayList<String>();
		RevenueBoxGloDTO revenueData = new RevenueBoxGloDTO();

		for (TerminosAuxiliarDTO periodo : ListaUtilerias.safeList(periodosAuxiliar))
			periodos.add(periodo.getFechaInicio() + "-" + periodo.getFechaFin());

		String tipoRevenue = obtenerTipoRevenue(idContrato, seccion);
		String tipoMinimo = minimo.obtenerTipoMinimo(idContrato, seccion);

		if (!MinimoTipos.CATEGORIA.equals(MinimoTipos.getSeccion(tipoMinimo))) {
			revenues = null;
		}

		if (RevenueTipos.GLOBAL.equals(RevenueTipos.getSeccion(tipoRevenue))) {
			revenues = null;
			revenueData.setRevenueBox(false);
			revenueData.setRevenueGlobal(true);
		} else {
			revenueData.setRevenueBox(true);
			revenueData.setRevenueGlobal(false);
		}

		RevenueSeccionDTO revenueBox = this.procesoRevenue(idContrato, minimos, revenues, periodos);
		revenueData.setDatosRevenueBox(revenueBox.getRevenue());
		revenueData.setPeriodos(revenueBox.getPeriodos());

		List<TerminosRevenueDTO> revenueGlobal = dao.obtenerRevenueMoviesGlobal(idContrato, seccion);
		String[][] global = this.proceseoRevenueGlobal(revenueGlobal);
		revenueData.setDatosRevenueGlobal(global);

		return revenueData;
	}

	public RevenueSeccionDTO procesoRevenue(Long idContrato, List<TerminoMinimoDTO> minimos,
			List<TerminosAuxiliarDTO> revenues, List<String> periodos) {
		RevenueSeccionDTO revenue = new RevenueSeccionDTO();

		if (periodos == null || periodos.isEmpty())
			periodos.add(feesDao.fechaInicio(idContrato) + "-" + feesDao.fechaFin(idContrato));

		if (minimos == null || minimos.size() == 0)
			minimos = Arrays.asList(new TerminoMinimoDTO("MFTV/MFV"));

		String datos[][] = new String[minimos.size()][(periodos.size() * 2) + 3];

		for (int i = 0; i < ListaUtilerias.safeList(minimos).size(); i++) {

			datos[i][0] = String.valueOf(minimos.get(i).getDesde());
			datos[i][1] = String.valueOf(minimos.get(i).getHasta());
			datos[i][2] = minimos.get(i).getCategoria();

			for (int j = 0; j < ListaUtilerias.safeList(revenues).size(); j++) {

				if (minimos.get(i).getId().equals(revenues.get(j).getId())) {
					for (int k = 0; k < periodos.size(); k++) {
						String fechaInicio = periodos.get(k).split("-")[0];

						if (fechaInicio.equals(revenues.get(j).getFechaInicio())) {

							datos[i][(k * 2) + 3] = revenues.get(j).getpDda();
							datos[i][(k * 2) + 4] = revenues.get(j).getpEstudio();

						}
					}
				}
			}

		}

		int cont = 0;
		for (int i = 0; i < datos.length; i++)
			if (datos[i][0] != null)
				cont++;

		String datos1[][] = new String[cont][(periodos.size() * 2) + 3];
		for (int i = 0; i < datos.length; i++) {
			if (datos[i][0] != null) {
				for (int j = 0; j < datos[0].length; j++)
					datos1[i][j] = datos[i][j];
			}
		}

		datos = datos1;

		String[] per = new String[periodos.size()];
		per = periodos.toArray(per);

		revenue.setPeriodos(per);
		revenue.setRevenue(datos);
		return revenue;
	}

	public void guardarRevenueBoxOfficeLibreria(Long idContrato, String seccion, RevenueBoxGloDTO revenue) {

		if (revenue != null) {
			Long idSeccion = dao.obtenerIdSeccion(idContrato, seccion);
			List<FsPeriodoDTO> pers = new ArrayList<FsPeriodoDTO>();
			List<TerminosAuxiliarDTO> revenues = new ArrayList<TerminosAuxiliarDTO>();

			if (revenue.getPeriodos() != null && revenue.getDatosRevenueBox() != null
					&& revenue.getDatosRevenueBox().length > 0 && revenue.getPeriodos().length > 0) {
				for (int i = 0; i < revenue.getPeriodos().length; i++) {
					String periodosExc[] = revenue.getPeriodos()[i].split("-");
					FsPeriodoDTO periodo = new FsPeriodoDTO();
					periodo.setFechaInicio(periodosExc[0]);
					periodo.setFechaFin(periodosExc[1]);
					periodo.setIdSeccion(idSeccion);
					periodo.setIdContrato(idContrato);
					periodo.setTipo(PeriodoTipos.REVENUE.getDesc());
					dao.guardarPeridoMinimos(periodo);
					pers.add(periodo);
				}

				for (int i = 0; i < revenue.getDatosRevenueBox().length; i++) {
					for (int j = 0; j < pers.size(); j++) {

						String desde = revenue.getDatosRevenueBox()[i][0];
						String hasta = revenue.getDatosRevenueBox()[i][1];

						TerminosAuxiliarDTO aux = new TerminosAuxiliarDTO();
						aux.setId(idContrato);
						aux.setIdOpcionalA(idSeccion);
						aux.setDesde(desde == null || desde.trim().equals("") ? "0" : desde);
						aux.setHasta(hasta == null || hasta.trim().equals("") ? "0" : hasta);
						aux.setNombre(revenue.getDatosRevenueBox()[i][2]);

						Long idCategoria = dao.obtenerIdMinimoPorValores(aux);

						TerminosAuxiliarDTO t = new TerminosAuxiliarDTO();
						t.setId(idCategoria);
						t.setIdOpcionalA(pers.get(j).getIdPeriodo());

						if (revenue.getDatosRevenueBox()[i][(j * 2) + 3] != null)
							t.setpDda(revenue.getDatosRevenueBox()[i][(j * 2) + 3]);
						if (revenue.getDatosRevenueBox()[i][(j * 2) + 4] != null)
							t.setpEstudio(revenue.getDatosRevenueBox()[i][(j * 2) + 4]);

						revenues.add(t);
					}
				}
				dao.guardarRevenueLibreriaBoxOffice(revenues);

			}
		}
	}

	public void eliminarMinimosCategoriasBoxOffice(Long idContrato, String seccion) {
		dao.eliminarMinimosCategoriasBoxOffice(idContrato, seccion);
	}

	public String obtenerTipoRevenue(Long idContrato, String seccion) {
		String tipo = dao.obtenerTipoRevenue(idContrato, seccion);
		return tipo == null || tipo.trim().equals("") ? RevenueTipos.GLOBAL.getDesc() : tipo;
	}

	public void guardarRevenueLibreria(Long idContrato, String seccion, RevenueBoxGloDTO revenue) {
		Long idSeccion = dao.obtenerIdSeccion(idContrato, seccion);
		if (revenue.isRevenueGlobal()) {

			List<TerminosRevenueDTO> revenues = new ArrayList<TerminosRevenueDTO>();

			for (int i = 0; i < revenue.getDatosRevenueGlobal().length; i++) {
				TerminosRevenueDTO t = new TerminosRevenueDTO();
				String fechas[] = revenue.getDatosRevenueGlobal()[i][0].split("-");

				t.setFechaInicio(fechas[0]);
				t.setFechaFin(fechas[1]);
				t.setDdaPto(revenue.getDatosRevenueGlobal()[i][1]);
				t.setEstudioPto(revenue.getDatosRevenueGlobal()[i][2]);
				revenues.add(t);
			}
			dao.actualizaTipoRevenue(idSeccion, RevenueTipos.GLOBAL.getDesc());
			dao.guardarValoresRevGlobal(idContrato, idSeccion, revenues);
		} else {
			dao.actualizaTipoRevenue(idSeccion, RevenueTipos.CATEGORIA.getDesc()); // RevenueTipos.BOX_OFFICE
			guardarRevenueBoxOfficeLibreria(idContrato, seccion, revenue);
		}
	}

}
