package jp.bne.deno.ordermaid.report;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;

import jp.bne.deno.ordermaid.common.ExcelReportBuilder;
import jp.bne.deno.ordermaid.dao.MenuItemTable;
import jp.bne.deno.ordermaid.dao.MenuTypeTable;
import jp.bne.deno.ordermaid.dao.OrderTable;
import jp.bne.deno.ordermaid.model.MenuItem;
import jp.bne.deno.ordermaid.model.MenuType;
import jp.bne.deno.ordermaid.model.OrderData;
import jp.bne.deno.ordermaid.model.OrderDetail;
import jp.bne.deno.ordermaid.model.OrderItem;
import jxl.format.Colour;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.WritableCellFormat;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

import com.google.inject.Inject;

public class SalesReportBuilder extends ExcelReportBuilder {

	@Inject
	OrderTable orderTable;

	@Inject
	MenuTypeTable menuTypeTable;

	@Inject
	MenuItemTable menuItemTable;

	/**
	 * 主処理実行.
	 */
	public void run(Calendar current) {
		setSheet("蓄積データ");
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd");
		SimpleDateFormat weekDayFormat = new SimpleDateFormat("E");
		SimpleDateFormat timeFormat = new SimpleDateFormat("HH");

		// 注文データ及びメニューマスタ取得.
		List<OrderData> list = orderTable.findOrderByMonth(current.getTime());
		List<MenuType> types = menuTypeTable.findAll();

		try {
			// ヘッダ行出力.
			WritableCellFormat cellFormatHeader = new WritableCellFormat();
			cellFormatHeader.setBackground(Colour.GRAY_25);

			sheet.addCell(new Label(0, 0, current.get(Calendar.YEAR) + "年",
					cellFormatHeader));
			sheet.addCell(new Label(1, 0, (current.get(Calendar.MONTH) + 1)
					+ "月", cellFormatHeader));
			sheet.addCell(new Label(6, 1, "並順", cellFormatHeader));
			sheet.addCell(new Label(6, 2, "価格", cellFormatHeader));
			sheet.addCell(new Label(6, 3, "商品名", cellFormatHeader));
			sheet.addCell(new Label(0, 3, "日付", cellFormatHeader));
			sheet.addCell(new Label(1, 3, "曜日", cellFormatHeader));
			sheet.addCell(new Label(2, 3, "時間", cellFormatHeader));
			sheet.addCell(new Label(3, 3, "注文ID", cellFormatHeader));
			sheet.addCell(new Label(4, 3, "性別", cellFormatHeader));
			sheet.addCell(new Label(5, 3, "店内/TO", cellFormatHeader));

			// メニュー一覧出力
			int col = 7;
			for (MenuType type : types) {
				for (MenuItem item : menuItemTable.findByTypeId(type
						.getMenuTypeId())) {
					String content = type.getSort() + "-" + item.getSort();
					sheet.addCell(new Label(col, 1, content, cellFormatHeader));
					double price = item.getPrice();
					sheet.addCell(new Number(col, 2, price, cellFormatHeader));
					content = item.getShortName();
					sheet.addCell(new Label(col, 3, content, cellFormatHeader));
					col++;
				}
			}

			// 明細出力.
			col = 0;
			int row = 4;
			for (OrderData data : list) {
				for (OrderDetail detail : data.getDetails()) {
					sheet.addCell(new Label(col++, row, dateFormat
							.format(detail.getOrder().getOrderDate())));
					sheet.addCell(new Label(col++, row, weekDayFormat
							.format(detail.getOrder().getOrderDate())));
					sheet.addCell(new Label(col++, row, timeFormat
							.format(detail.getOrder().getOrderDate())));

					sheet.addCell(new jxl.write.Number(col++, row, detail
							.getOrder().getOrderId()));
					sheet.addCell(new Label(col++, row, detail.getSex()));
					if (detail.isTakeOut()) {
						sheet.addCell(new Label(col++, row, "TO"));
					} else {
						sheet.addCell(new Label(col++, row, "店内"));
					}
					double sumPrice = detail.getSumPrice();
					sheet.addCell(new Number(col++, row, sumPrice));
					for (MenuType type : types) {
						double amount = 0;
						for (MenuItem item : menuItemTable.findByTypeId(type
								.getMenuTypeId())) {
							for (OrderItem orderItem : detail.getItems()) {
								if (orderItem.getMenuItem().getMenuId() == item
										.getMenuId()) {
									amount += item.getTypeAmount();
									sheet.addCell(new Number(col, row, amount));
								}
							}
							col++;
						}
					}
					// 次の行に進む.
					col = 0;
					row++;
				}
			}

			writeOut();
		} catch (RowsExceededException e) {
			e.printStackTrace();
		} catch (WriteException e) {
			e.printStackTrace();
		}

	}
}
