/*******************************************************************************
 * Copyright 2019 2Fi Business Solutions Ltd.
 *
 *
 *
 * This code is copyrighted. Under no circumstances should any party, people,
 * or organization should redistribute any portions of this code in any form,
 * either verbatim or through electronic media, to any third parties, unless
 * under explicit written permission by 2Fi Business Solutions Ltd.
 ******************************************************************************/
package com.ffii.tbms.reports.service;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.ffii.core.dao.JdbcDao;
import com.ffii.core.utils.MapUtils;
import com.ffii.core.utils.SecurityUtils;
import com.ffii.core.web.AbstractService;
import com.ffii.tbms.order.Order;

/**
 * @author fung
 */
@Service
public class PaymentReportService extends AbstractService {

	@Autowired
	private JdbcDao jdbcDao;

	@Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
	public List<Map<String, Object>> search(Map<String, Object> args) {

		SecurityUtils.authArgs(args);

		StringBuilder sql = new StringBuilder(
			" SELECT o.id AS orderId, "
			+" p.id AS paymentId, "
			+" o.date AS orderDate, "
			+" MAX(p.date) AS paymentDate, "
			+" o.type, "
			+" o.code, "
			+" CONCAT(o.type, o.code) AS orderNo, "
			+" o.refNo AS orderRef, "
			+" c.id AS custId, "
			+" c.email, "
			+" concat_ws(' / ', c.phone1, c.phone2) AS phone, "
			+" concat_ws(' ', c.firstName ,c.surname, c.nameCh) AS customerName, "
			+" o.status AS orderStatus, "
			+" _o.orderAmount, "
			+" SUM(p.amount) AS paymentAmount "
			+" FROM payment p "
			+" LEFT JOIN orders o ON p.orderId = o.id "
			+" LEFT JOIN customer c ON c.id = o.custId "
			+" LEFT JOIN (SELECT oi.orderId, "
			+" SUM(oi.price) AS orderAmount "
				+" FROM order_item oi WHERE oi.deleted = 0 "
				+" GROUP BY oi.orderId) _o ON _o.orderId = o.id "
			+" WHERE o.deleted = 0 AND p.deleted = 0  AND o.id IS NOT NULL AND o.status >= "+Order.STATUS_CANCELLED+" ");
		if (args != null) {
			if (args.containsKey("dateFrom")) sql.append(" AND p.date >= :dateFrom ");
			if (args.containsKey("dateTo")) sql.append(" AND p.date <= :dateTo ");
			if(args.containsKey("sysGroupId")){
				sql.append(" AND o.sysGroupId = :sysGroupId AND p.sysGroupId = :sysGroupId ");
			}
		}

		sql.append(" GROUP BY o.id ORDER BY paymentDate ASC, o.id ASC ");

		if(args != null){
			if (args.containsKey("start") && args.containsKey("limit"))
				sql.append(" LIMIT :start, :limit ");
		}

		return jdbcDao.queryForList(sql.toString(), args);
	}

	@Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
	public Map<String, Object> count(Map<String, Object> args) {

		SecurityUtils.authArgs(args);
		StringBuilder sql = new StringBuilder(
			" SELECT count(distinct o.id) As count "
			+" FROM payment p "
			+" LEFT JOIN orders o ON p.orderId = o.id "
			+" WHERE o.deleted = 0 AND p.deleted = 0  AND o.id IS NOT NULL AND o.status >= "+Order.STATUS_CANCELLED+" ");
		if (args != null) {
			if (args.containsKey("dateFrom")) sql.append(" AND p.date >= :dateFrom ");
			if (args.containsKey("dateTo")) sql.append(" AND p.date <= :dateTo ");
			if(args.containsKey("sysGroupId")){
				sql.append(" AND o.sysGroupId = :sysGroupId AND p.sysGroupId = :sysGroupId ");
			}
		};

		return jdbcDao.queryForMap(sql.toString(), args);
	}

	@Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
	public Map<String, Object> searchCurrentPayment(int orderId) {

		Map<String,Object> args = MapUtils.toHashMap("orderId", orderId);
		SecurityUtils.authArgs(args);
		
		StringBuilder sql = new StringBuilder(
			" SELECT SUM(p.amount) AS currentPayment FROM payment p WHERE p.deleted = 0 AND p.orderId = :orderId ");

			if (args != null) {
				if(args.containsKey("sysGroupId")){
					sql.append(" AND p.sysGroupId = :sysGroupId ");
				}
			};

		return jdbcDao.queryForMap(sql.toString(), args);
	}


}
