/*************************************************************************************************
 * 프로그램명 : ReportsView.java 프로그램설명 : 집계자가 올린 프로젝트 리스트 작성자 : 강원중 작성일 : 2004.01.27 변경일 : 2003.11.30
 **************************************************************************************************/

package kr.co.kihyun.beans.totsys.report;

import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import kr.co.kihyun.beans.entity.MDept;
import kr.co.kihyun.beans.entity.MUser;
import kr.co.kihyun.beans.entity.MoumiEntity;
import kr.co.kihyun.beans.entity.TotDoc;

import kr.co.kihyun.beans.entity.TotReport;
import kr.co.kihyun.beans.entity.TotReportProcess;
import kr.co.kihyun.beans.entity.TotReportType;
import kr.co.kihyun.db.DBManager;
import kr.co.kihyun.db.FixMeJDOException;
import kr.co.kihyun.lang.MString;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ReportsView extends DBManager {
	private static final Logger LOG = LoggerFactory.getLogger(ReportsView.class);

	private ResultSet rs = null;

	private int count = 0;
	private int notCount = 0;
	private List<String> partIDList = null;
	private List<String> partNameList = null;
	private List<String> deptIDList = null;
	private List<String> deptNameList = null;
	private List<Date> regDateList = null;
	private List<String> userIDList = null;
	private List<String> userNameList = null;
	private List<String> noteList = null;
	private List<String> datasList = null;
	private List<String> totDatasList = null;
	private List<Long> downDocIDList = null;
	private StringBuilder totDatasBuf = null;
	private StringBuilder datasBuf = null;
	private StringBuilder tableRows = null;
	private List<String> locationList = null;
	private List<String> gradeList = null;
	private List<String> foundationList = null;
	private List<Integer> rowCountList = null;
	private List<Integer> prssList = null;

	@Override
	protected void setStatment(String sql, Object... params) throws SQLException, FixMeJDOException {
		if (con == null || con.isClosed()) {
			con = getConnection();
		}
			pstmt = con.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
		for (int i = 0; params != null && i < params.length; i++) {
			if (params[i] instanceof java.util.Date) {
				java.util.Date param = (java.util.Date) params[i];
				pstmt.setDate(i + 1, new java.sql.Date(param.getTime()));
			} else if (params[i] instanceof Boolean) {
				pstmt.setBoolean(i + 1, (Boolean) params[i]);
			} else {
				pstmt.setObject(i + 1, params[i]);
			}
		}
	}

	/********************* 집계문서의 전체 보고자료 *******************/
	public void executeQuery(Long docID) {
		executeQuery(docID, null);
	}

	public void executeQuery(Long docID, String partID) {
		StringBuilder sql = new StringBuilder(750);

		totDatasBuf = new StringBuilder();
		datasBuf = new StringBuilder();

		StringBuilder datasAll = new StringBuilder();
		StringBuilder totDatasAll = new StringBuilder();

		try {
			sql.append("select pt.id, pt.name, dt.id, dt.name, dt.location, dt.grade, dt.foundation, us.id, ")
					.append("sp_cm_dec_fu(us.name), rt.reg_date, ")
					.append("(length(rt.data)-length(replace(rt.data,'!%','')))/length('!%') row_count, rt.data, ")
					.append("rt.tot_data, rt.note, rt.down_doc_id, rt.prss from ")
					.append(MoumiEntity.getTableName(TotDoc.class)).append(" dc, ")
					.append(MoumiEntity.getTableName(TotReport.class)).append(" rt, ")
					.append(MoumiEntity.getTableName(MUser.class)).append(" us, ")
					.append(MoumiEntity.getTableName(MDept.class)).append(" dt, ")
					.append(MoumiEntity.getTableName(MDept.class)).append(" pt ")
					.append("where (dc.id=? and (dc.del_type='0' or dc.del_type='N')) ")
					.append("and (rt.doc_id=? and rt.prss>=? and rt.prss<9 and (rt.del_type='0' or rt.del_type='N') ")
					.append("and rt.type=? and data is not null) ")
					.append("and rt.user_id=us.id and rt.dept_id=dt.id and dt.organ=pt.id");
			if (partID != null)
				sql.append(" and pt.id=?");
			sql.append(" order by dt.priority, dt.upper_dept, dt.name");
			if (partID != null){
				rs = execQuery(sql.toString(), docID, docID, TotReportProcess.COMP.ordinal(), TotReportType.REPORT.ordinal(), partID);
			}else{
				rs = execQuery(sql.toString(), docID, docID, TotReportProcess.COMP.ordinal(), TotReportType.REPORT.ordinal());
			}


			partIDList = new ArrayList<String>();
			partNameList = new ArrayList<String>();
			deptIDList = new ArrayList<String>();
			deptNameList = new ArrayList<String>();
			regDateList = new ArrayList<Date>();
			userIDList = new ArrayList<String>();
			userNameList = new ArrayList<String>();
			noteList = new ArrayList<String>();
			rowCountList = new ArrayList<Integer>();
			datasList = new ArrayList<String>();
			totDatasList = new ArrayList<String>();
			downDocIDList = new ArrayList<Long>();
			locationList = new ArrayList<String>();
			gradeList = new ArrayList<String>();
			foundationList = new ArrayList<String>();
			prssList = new ArrayList<Integer>();

			for (int i = 0; rs.next(); i++) {
				partIDList.add(rs.getString(1));
				partNameList.add(rs.getString(2));
				deptIDList.add(rs.getString(3));
				deptNameList.add(rs.getString(4));
				locationList.add(rs.getString(5));
				gradeList.add(rs.getString(6));
				foundationList.add(rs.getString(7));
				userIDList.add(rs.getString(8));
				userNameList.add(rs.getString(9));
				regDateList.add(rs.getDate(10));
				rowCountList.add(rs.getInt(11));
				datasList.add(MString.checkNull(rs.getString(12)));
				totDatasList.add(MString.checkNull(rs.getString(13)));
				noteList.add(MString.checkNull(rs.getString(14)));
				downDocIDList.add(rs.getLong(15));
				prssList.add(rs.getInt(16));

				if (i == 0) {
					totDatasAll.append(totDatasList.get(i));
				} else {
					String inData[] = totDatasAll.toString().split(TotReport.TABLE_DELIMITER); // 테이블 별로
					String inst[] = totDatasList.get(i).split(TotReport.TABLE_DELIMITER); // 테이블 별로

					for (int set = 0; set < inData.length; set++) {
						inData[set] = inData[set] + TotReport.ROW_DELIMITER + inst[set];
					}

					for (int set = 0; set < inData.length; set++) {
						if (set == 0) {
							totDatasAll.append(inData[set]);
						} else {
							totDatasAll.append(TotReport.TABLE_DELIMITER);
							totDatasAll.append(inData[set]);
						}
					}
				}

				if (i == 0) {
					datasAll.append(datasList.get(i));
				} else {
					String inData[] = datasAll.toString().split(TotReport.TABLE_DELIMITER); // 테이블 별로
					String inst[] = datasList.get(i).split(TotReport.TABLE_DELIMITER); // 테이블 별로

					for (int set = 0; set < inData.length; set++) {
						inData[set] = inData[set] + TotReport.ROW_DELIMITER + inst[set];
					}

					for (int set = 0; set < inData.length; set++) {
						if (set == 0) {
							datasAll.append(inData[set]);
						} else {
							datasAll.append(TotReport.TABLE_DELIMITER);
							datasAll.append(inData[set]);
						}
					}
				}
			}

			if(null != rs) rs.close();
			pstmt.close();

			count = partIDList.size();
			datasBuf.append(datasAll.toString());
			totDatasBuf.append(totDatasAll.toString());
			tableRows = new StringBuilder();
			/******* 각 테이블 마다 행의 갯수 파악 ********/
			String tableList[] = datasAll.toString().split(TotReport.TABLE_DELIMITER);
			for (int tr = 0; tr < tableList.length; tr++) {
				int rowcount = (tableList[tr].split(TotReport.ROW_DELIMITER)).length;
				if (tr == 0) {
					tableRows.append(Integer.toString(rowcount));
				} else {
					tableRows.append(",");
					tableRows.append(Integer.toString(rowcount));
				}
			}
			/****** 각 테이블 마다 행의 갯수 파악 끝 *******/



			sql = new StringBuilder(300);
			if (partID == null) {
				sql.append("select count(rt.dept_id) from ")
						.append(MoumiEntity.getTableName(TotDoc.class)).append(" dc, ")
						.append(MoumiEntity.getTableName(TotReport.class)).append(" rt, ")
						.append(MoumiEntity.getTableName(MUser.class)).append(" us ")
						.append("where (dc.id=? and (dc.del_type='0' or dc.del_type='N')) ")
						.append("and (rt.doc_id=? and rt.prss=? and (rt.del_type='0' or rt.del_type='N') ")
						.append("and rt.type=?) and rt.user_id=us.id");
				rs = execQuery(sql.toString(), docID, docID, TotReportProcess.NOT.ordinal(), TotReportType.REPORT.ordinal());
			} else {
				sql.append("select count(rt.dept_id) from ")
						.append(MoumiEntity.getTableName(TotDoc.class)).append(" dc, ")
						.append(MoumiEntity.getTableName(TotReport.class)).append(" rt, ")
						.append(MoumiEntity.getTableName(MUser.class)).append(" us, ")
						.append(MoumiEntity.getTableName(MDept.class)).append(" dt ")
						.append("where (dc.id=? and (dc.del_type='0' or dc.del_type='N')) ")
						.append("and (rt.doc_id=? and rt.prss=? and (rt.del_type='0' or rt.del_type='N') ")
						.append("and rt.type=?) and rt.user_id=us.id and us.dept_id=dt.id and dt.organ=?");
				rs = execQuery(sql.toString(), docID, docID, TotReportProcess.NOT.ordinal(), TotReportType.REPORT.ordinal(), partID);
			}

			notCount = rs.next() ? rs.getInt(1) : 0;
			if(null != rs) rs.close();
			pstmt.close();

		} catch (SQLException sqlEx) {
			LOG.error("\nSQLState - {}\nMySQL Error Code - {}\nmessage - {}\nsql - {}",
					new Object[] { sqlEx.getSQLState(), sqlEx.getErrorCode(), sqlEx.getMessage(), sql });
			throw new RuntimeException(sqlEx);
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		} finally {
			close(rs);
			execClose();
		}
	}

	public void executeAllQuery(Long docID, String partID) {
		executeAllQuery(docID, partID, -1);
	}

	public void executeAllQuery(Long docID, String partID, int searchType) {
		StringBuilder sql = new StringBuilder(2000);
		totDatasBuf = new StringBuilder();
		datasBuf = new StringBuilder();

		StringBuilder datasAll = new StringBuilder();
		StringBuilder totDatasAll = new StringBuilder();

		try {
			sql.append("(SELECT pt.name, dt.id dt_id, dt.name dt_name, dt.location, dt.grade, dt.foundation, ")
					.append("us.id, sp_cm_dec_fu(us.name), rt.reg_date, (length(rt.data)-length(replace(rt.data,'!%','')))/length('!%') row_count, ")
					.append("rt.data, rt.tot_data, rt.note, rt.down_doc_id, pt.id pt_id, ")
					.append("dt.priority dt_priority, dt.organ dt_organ, dt.upper_dept dt_upper_dept, rt.prss ")
					.append("FROM ").append(MoumiEntity.getTableName(TotDoc.class)).append(" dc, ")
					.append(MoumiEntity.getTableName(TotReport.class)).append(" rt LEFT JOIN ")
					.append(MoumiEntity.getTableName(MUser.class)).append(" us ON (rt.user_id=us.id), ")
					.append(MoumiEntity.getTableName(MDept.class)).append(" dt, ")
					.append(MoumiEntity.getTableName(MDept.class)).append(" pt ")
					.append("WHERE (dc.id='").append(docID).append("' and (dc.del_type='0' or dc.del_type='N')) ");
			if (searchType == TotReportProcess.COMP.ordinal()) {
				sql.append(" and rt.prss=")
						.append(TotReportProcess.COMP.ordinal())
						.append(" ");
			} else if (searchType > -1) {
				sql.append(" and rt.prss<>")
						.append(TotReportProcess.COMP.ordinal())
						.append(" ");
			}

			sql.append("and (rt.doc_id='")
					.append(docID)
					.append("' and (rt.del_type='0' or rt.del_type='N') and rt.type=0) ")
					.append("and rt.dept_id=dt.id and dt.organ=pt.id ")
					.append("and (rt.down_doc_id is null or rt.down_doc_id='')");
			if (partID != null) {
				sql.append("and pt.id='")
						.append(partID)
						.append("'");
			}
			sql.append(") UNION ALL")
					.append("(SELECT d_pt.name, d_dt.id, d_dt.name dt_name, d_dt.location, d_dt.grade, ")
					.append("d_dt.foundation, d_us.id, sp_cm_dec_fu(d_us.name), d_rt.reg_date, ")
					.append("(length(d_rt.data)-length(replace(d_rt.data,'!%','')))/length('!%') row_count, ")
					.append("d_rt.data, d_rt.tot_data, d_rt.note, d_rt.down_doc_id, ")
					.append("d_pt.id pt_id, d_dt.priority dt_priority, dt.organ dt_organ, d_dt.upper_dept dt_upper_dept, ")
					.append("d_rt.prss ")
					.append("FROM ").append(MoumiEntity.getTableName(TotDoc.class)).append(" dc, ")
					.append(MoumiEntity.getTableName(TotDoc.class)).append(" d_dc, ")
					.append("").append(MoumiEntity.getTableName(TotReport.class)).append(" rt LEFT JOIN ")
					.append(MoumiEntity.getTableName(MUser.class)).append(" us ON (rt.user_id=us.id), ")
					.append(MoumiEntity.getTableName(MDept.class)).append(" dt, ")
					.append(MoumiEntity.getTableName(MDept.class)).append(" pt, ")
					.append(MoumiEntity.getTableName(TotReport.class)).append(" d_rt LEFT JOIN ")
					.append(MoumiEntity.getTableName(MUser.class)).append(" d_us ON (d_rt.user_id=d_us.id), ")
					.append(MoumiEntity.getTableName(MDept.class)).append(" d_dt, ")
					.append(MoumiEntity.getTableName(MDept.class)).append(" d_pt ")
					.append("WHERE (dc.id='").append(docID).append("' and (dc.del_type='0' or dc.del_type='N')) ");
			if (searchType == TotReportProcess.COMP.ordinal()) {
				sql.append(" and d_rt.prss=")
						.append(TotReportProcess.COMP.ordinal())
						.append(" ");
			} else if (searchType > -1) {
				sql.append(" and d_rt.prss<>")
						.append(TotReportProcess.COMP.ordinal())
						.append(" ");
			}

			sql.append("and (rt.doc_id='")
					.append(docID)
					.append("' and (rt.del_type='0' or rt.del_type='N') and rt.type=0) ")
					.append("and rt.dept_id=dt.id and dt.organ=pt.id and rt.down_doc_id=d_dc.id ")
					.append("and d_rt.doc_id=d_dc.id and d_dt.id=d_rt.dept_id and d_dt.organ=d_pt.id ")
					.append("and d_dt.id=d_rt.dept_id and (d_dc.del_type='0' or d_dc.del_type='N') ")
					.append("and (d_rt.del_type='0' or d_rt.del_type='N') and d_rt.type=0 ");
			if (partID != null) {
				sql.append("and pt.id='").append(partID).append("' ");
			}
			sql.append(") order by dt_priority, dt_upper_dept, dt_name");



			rs = execQuery(sql.toString());

			if (rs != null) {
				rs.last();
				count = rs.getRow();
				rs.beforeFirst();
			} else {
				return;
			}
			partIDList = new ArrayList<String>();
			partNameList = new ArrayList<String>();
			deptIDList = new ArrayList<String>();
			deptNameList = new ArrayList<String>();
			regDateList = new ArrayList<Date>();
			userIDList = new ArrayList<String>();
			userNameList = new ArrayList<String>();
			noteList = new ArrayList<String>();
			rowCountList = new ArrayList<Integer>();
			datasList = new ArrayList<String>();
			totDatasList = new ArrayList<String>();
			downDocIDList = new ArrayList<Long>();
			locationList = new ArrayList<String>();
			gradeList = new ArrayList<String>();
			foundationList = new ArrayList<String>();
			prssList = new ArrayList<Integer>();

			for (int i = 0; rs.next(); i++) {
				// rs2의 값 배열에 저장
				partNameList.add(MString.checkNull(rs.getString(1)));
				deptIDList.add(rs.getString(2));
				deptNameList.add(MString.checkNull(rs.getString(3)));
				locationList.add(MString.checkNull(rs.getString(4)));
				gradeList.add(MString.checkNull(rs.getString(5)));
				foundationList.add(MString.checkNull(rs.getString(6)));
				userIDList.add(MString.checkNull(rs.getString(7)));
				userNameList.add(MString.checkNull(rs.getString(8)));
				regDateList.add(rs.getDate(9));
				rowCountList.add(rs.getInt(10));
				datasList.add(MString.checkNull(rs.getString(11)));
				totDatasList.add(MString.checkNull(rs.getString(12)));
				noteList.add(MString.checkNull(rs.getString(13)));
				downDocIDList.add(rs.getLong(14));
				partIDList.add(rs.getString(15));
				prssList.add(rs.getInt(19));

				if (i == 0) {
					// totDatasBuf.append(totDatasList.get(i));
					totDatasAll.append(totDatasList.get(i));
				} else {
					// totDatasBuf.append(MReport.splitStr1+totDatasList.get(i));
					// totDatasBuf.append(TotReport.ROW_DELIMITER+totDatasList.get(i));
					String inData[] = totDatasAll.toString().split(TotReport.TABLE_DELIMITER); // 테이블 별로
					String inst[] = totDatasList.get(i).split(TotReport.TABLE_DELIMITER); // 테이블 별로

					for (int set = 0; set < inData.length && set < inst.length; set++) {
						inData[set] = inData[set] + TotReport.ROW_DELIMITER + inst[set];
					}

					for (int set = 0; set < inData.length; set++) {
						if (set == 0) {
							totDatasAll.append(inData[set]);
						} else {
							totDatasAll.append(TotReport.TABLE_DELIMITER);
							totDatasAll.append(inData[set]);
						}
					}
				}

				if (i == 0) {
					// datasBuf.append(datasList.get(i));
					datasAll.append(datasList.get(i));
				} else {
					// datasBuf.append(MReport.splitStr1+datasList.get(i));
					// datasBuf.append(TotReport.ROW_DELIMITER+datasList.get(i));

					String inData[] = datasAll.toString().split(TotReport.TABLE_DELIMITER); // 테이블 별로
					String inst[] = datasList.get(i).split(TotReport.TABLE_DELIMITER); // 테이블 별로

					for (int set = 0; set < inData.length && set < inst.length; set++) {
						inData[set] = inData[set] + TotReport.ROW_DELIMITER + inst[set];
					}

					for (int set = 0; set < inData.length; set++) {
						if (set == 0) {
							datasAll.append(inData[set]);
						} else {
							datasAll.append(TotReport.TABLE_DELIMITER);
							datasAll.append(inData[set]);
						}
					}
				}
			}

			if(null != rs) rs.close();
			pstmt.close();

			datasBuf.append(datasAll.toString());
			totDatasBuf.append(totDatasAll.toString());

			/******* 각 테이블 마다 행의 갯수 파악 ********/
			String tableList[] = datasAll.toString().split(TotReport.TABLE_DELIMITER);
			tableRows = new StringBuilder();
			for (int tr = 0; tr < tableList.length; tr++) {
				int rowcount = (tableList[tr].split(TotReport.ROW_DELIMITER)).length;
				if (tr == 0) {
					tableRows.append(Integer.toString(rowcount));
				} else {
					tableRows.append(",")
							.append(Integer.toString(rowcount));
				}
			}
			/****** 각 테이블 마다 행의 갯수 파악 끝 *******/

			// 해당없음 카운트
			sql = new StringBuilder();
			if (partID == null) {
				sql.append("select count(*) ")
						.append("from ").append(MoumiEntity.getTableName(TotDoc.class)).append(" dc, ")
						.append(MoumiEntity.getTableName(TotReport.class)).append(" rt, ")
						.append(MoumiEntity.getTableName(MUser.class)).append(" us ")
						.append("where (dc.id='").append(docID).append("' ")
						.append("and (dc.del_type='0' or dc.del_type='N')) ")
						.append("and (rt.doc_id='").append(docID).append("' ")
						.append("and rt.prss=").append(TotReportProcess.NOT.ordinal()).append(" ")
						.append("and (rt.del_type='0' or rt.del_type='N') ")
						.append("and rt.type=").append(TotReportType.REPORT.ordinal()).append(") and rt.user_id=us.id");
			} else {
				sql.append("select count(*) cnt ")
						.append("from ").append(MoumiEntity.getTableName(TotDoc.class)).append(" dc, ")
						.append(MoumiEntity.getTableName(TotReport.class)).append(" rt, ")
						.append(MoumiEntity.getTableName(MUser.class)).append(" us, ")
						.append(MoumiEntity.getTableName(MDept.class)).append(" dt ")
						.append("where (dc.id='").append(docID).append("' ")
						.append("and (dc.del_type='0' or dc.del_type='N')) ")
						.append("and (rt.doc_id='").append(docID).append("' ")
						.append("and rt.prss=").append(TotReportProcess.NOT.ordinal()).append(" ")
						.append("and (rt.del_type='0' or rt.del_type='N') ")
						.append("and rt.type=").append(TotReportType.REPORT.ordinal()).append(") ")
						.append("and rt.user_id=us.id and us.dept_id=dt.id ")
						.append("and dt.organ='").append(partID).append("'");
			}

			rs = execQuery(sql.toString());
			notCount = rs.next() ? rs.getInt(1) : 0;
			if(null != rs) rs.close();
			pstmt.close();
		} catch (SQLException sqlEx) {
			LOG.error("\nSQLState - {}\nMySQL Error Code - {}\nmessage - {}\nsql - {}",
					new Object[] { sqlEx.getSQLState(), sqlEx.getErrorCode(), sqlEx.getMessage(), sql.toString() });
			throw new RuntimeException(sqlEx);
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		} finally {
			close(rs);
			execClose();
		}
	}

	/******** 보고자료의 각 Field값 얻는 Method ********/
	public int getCount() {
		return count;
	}

	public int getNotCount() {
		return notCount;
	}

	public String[] getPartNameList() {
		return partNameList.toArray(new String[partNameList.size()]);
	}

	public String[] getPartIDList() {
		return partIDList.toArray(new String[partIDList.size()]);
	}

	public String[] getDeptIDList() {
		return deptIDList.toArray(new String[deptIDList.size()]);
	}

	public String[] getDeptNameList() {
		return deptNameList.toArray(new String[deptNameList.size()]);
	}

	public Date[] getRegDateList() {
		return regDateList.toArray(new Date[regDateList.size()]);
	}

	public String[] getUserIDList() {
		return userIDList.toArray(new String[userIDList.size()]);
	}

	public String[] getUserNameList() {
		return userNameList.toArray(new String[userNameList.size()]);
	}

	public String[] getNoteList() {
		return noteList.toArray(new String[noteList.size()]);
	}

	public Integer[] getRowCountList() {
		return rowCountList.toArray(new Integer[rowCountList.size()]);
	}

	public String[] getDatasList() {
		return datasList.toArray(new String[datasList.size()]);
	}

	public String[] getTotDatasList() {
		return totDatasList.toArray(new String[totDatasList.size()]);
	}

	public String getTotDatas() {
		return totDatasBuf.toString();
	}

	public String getDatas() {
		return datasBuf.toString();
	}

	public Long[] getDownDocIDList() {
		return downDocIDList.toArray(new Long[downDocIDList.size()]);
	}

	public String getPartName() {
		if (count > 0)
			return partNameList.get(0);
		return "";
	}

	public String getTableRows() {
		return tableRows.toString();
	}

	public String[] getLocationList() {
		return locationList.toArray(new String[locationList.size()]);
	}

	public String[] getGradeList() {
		return gradeList.toArray(new String[gradeList.size()]);
	}

	public String[] getFoundationList() {
		return foundationList.toArray(new String[foundationList.size()]);
	}

	public Integer[] getPrssList() {
		return prssList.toArray(new Integer[prssList.size()]);
	}
}
