package ru.yandex.wmconsole.common.service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import org.springframework.jdbc.core.simple.ParameterizedRowMapper;

import ru.yandex.wmconsole.data.partition.WMCPartition;
import ru.yandex.wmtools.common.data.info.VisitingStatInfo;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.wmtools.common.service.VisitingStatService;

/**
 * Created by IntelliJ IDEA.
 * User: senin
 * Date: 20.03.2007
 * Time: 10:09:24
 */

public class WMCVisitingStatService extends VisitingStatService {
    private static final String FIELD_USER_ID = "user_id";
    private static final String FIELD_REQUEST_DATE = "request_date";
    private static final String FIELD_REQUEST_TYPE_ID = "request_type_id";
    private static final String FIELD_REQUEST_TYPE_NAME = "request_type_name";
    private static final String FIELD_COUNT = "count";
    private static final String FIELD_ID = "id";
    private static final String FIELD_NAME = "name";

    private static final String SELECT_REQUEST_TYPE_QUERY = "" +
            "SELECT " +
            "   id AS " + FIELD_ID + ", " +
            "   name AS " + FIELD_NAME + " " +
            "FROM " +
            "   tbl_dic_request_type";

    private static final String INSERT_USER_REQUEST_COUNT_QUERY = "" +
            "INSERT INTO tbl_user_requests_count (request_date, user_id, request_type, count) VALUES (?, ?, ?, ?) " +
            "ON DUPLICATE KEY UPDATE count = count + VALUES(count)";

    private static final String SELECT_VISITING_STAT_FOR_USER_QUERY = "" +
            "SELECT " +
            "    urc.user_id AS " + FIELD_USER_ID + ", " +
            "    urc.request_date AS " + FIELD_REQUEST_DATE + ", " +
            "    urc.request_type AS " + FIELD_REQUEST_TYPE_ID + ", " +
            "    drt.name AS " + FIELD_REQUEST_TYPE_NAME + ", " +
            "    urc.count AS " + FIELD_COUNT + " " +
            "FROM " +
            "    tbl_user_requests_count urc, " +
            "    tbl_dic_request_type drt " +
            "WHERE " +
            "    urc.request_type = drt.id " +
            "AND " +
            "    urc.user_id = ? " +
            "AND " +
            "    urc.request_date = ? ";

    private static final String SELECT_VISITING_STAT_QUERY = "" +
            "SELECT " +
            "    NULL AS " + FIELD_USER_ID + ", " +
            "    MAX(urc.request_date) AS " + FIELD_REQUEST_DATE + ", " +
            "    urc.request_type AS " + FIELD_REQUEST_TYPE_ID + ", " +
            "    drt.name AS " + FIELD_REQUEST_TYPE_NAME + ", " +
            "    SUM(urc.count) AS " + FIELD_COUNT + " " +
            "FROM " +
            "    tbl_user_requests_count urc, " +
            "    tbl_dic_request_type drt " +
            "WHERE " +
            "    urc.request_type = drt.id " +
            "AND " +
            "    urc.request_date = ? " +
            "GROUP BY " +
            "    urc.request_type ";

    private final ParameterizedRowMapper<RequestType> requestTypeRowMapper = new ParameterizedRowMapper<RequestType>() {
        @Override
        public RequestType mapRow(ResultSet resultSet, int i) throws SQLException {
            String name = resultSet.getString(FIELD_NAME);
            int id = resultSet.getInt(FIELD_ID);
            return new RequestType(name, id);
        }
    };

    private final ParameterizedRowMapper<VisitingStatInfo> visitingStatRowMapper = new ParameterizedRowMapper<VisitingStatInfo>() {
        @Override
        public VisitingStatInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
            Long userId = rs.getLong(FIELD_USER_ID);
            if (rs.wasNull()) {
                userId = null;
            }

            Date requestDate = rs.getDate(FIELD_REQUEST_DATE);
            int requestTypeId = rs.getInt(FIELD_REQUEST_TYPE_ID);
            String requestTypeName = rs.getString(FIELD_REQUEST_TYPE_NAME);
            Integer count = rs.getInt(FIELD_COUNT);

            return new VisitingStatInfo(userId, requestTypeId, requestTypeName, requestDate, count);
        }
    };

    @Override
    protected List<RequestType> getRequestTypeSelectQuery2() throws InternalException {
        return getJdbcTemplate(WMCPartition.nullPartition()).query(SELECT_REQUEST_TYPE_QUERY, requestTypeRowMapper);
    }

    @Override
    protected void getUserRequestCountUpdateQuery(Date date, long userId, long count, String requestName) throws InternalException {
        getJdbcTemplate(WMCPartition.nullPartition()).update(INSERT_USER_REQUEST_COUNT_QUERY, date, userId, getRequestId(requestName), count);
    }

    @Override
    protected List<VisitingStatInfo> getVisitingStatForUserQuery(Date date, Long userId) throws InternalException {
        return getJdbcTemplate(WMCPartition.nullPartition()).query(SELECT_VISITING_STAT_FOR_USER_QUERY, visitingStatRowMapper, userId, date);
    }

    @Override
    protected List<VisitingStatInfo> getVisitingStatQuery(Date date) throws InternalException {
        return getJdbcTemplate(WMCPartition.nullPartition()).query(SELECT_VISITING_STAT_QUERY, visitingStatRowMapper, date);
    }
}
