package de.lcag.common;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.List;

import javax.naming.ConfigurationException;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class ExcelHashTableTest {
	private Path resDir = Path.of("src/test/resources/ExcelTable");

	@BeforeAll
	static void setUpBeforeClass() throws Exception {
	}

	@BeforeEach
	void setUp() throws Exception {
	}

	@Test
	void testSave() throws IOException {
		CsvTable csv = new CsvTable("CsvTable/NameList.csv");
		csv.read();

		ExcelHashTable excel = new ExcelHashTable("src/test/resources/results/NameList.xlsx");

		excel.append(csv);
		excel.save();
	}

	@Test
	void testRead() throws IOException, ConfigurationException {
		ExcelWorkbook excel;
		int noRows = -1;
		List<String> wantedColumns = List.of("Code", "ValidFrom", "Name", "Latitude", "Longitude", "X", "Y");
		List<String> keyFields = List.of("Code", "ValidFrom");
		CsvTable mappingTableCSV = new CsvTable("EntityFieldMapping.csv");

		mappingTableCSV.read();
		noRows = mappingTableCSV.lenght();
		assertEquals(37, noRows);

		excel = new ExcelWorkbook("src/test/resources/results/NameList.xlsx");
		excel.read();
		noRows = excel.lenght();
		assertEquals(4, noRows);

		// TODO: Test read using mapping table
		MappingTable mappingTable = new MappingTable(mappingTableCSV);

	}

	@Test
	void testReadLimitedWithKeys() throws IOException, ConfigurationException {
		ExcelHashTable excel;
		int noRows = -1;
		int noRowsLimit = 5;
		List<String> wantedColumns = List.of("Code", "Valid From", "Name", "Latitude", "Longitude", "X", "Y");
		List<String> keyFields = List.of("Code", "Valid From");

		excel = new ExcelHashTable("src/test/resources/ExcelTable/City-BeforeCorrection.xlsx");
		excel.setOption(Table.OPTION_LIMIT_NUMBER_ROWS, noRowsLimit);
		excel.setWantedColumns(wantedColumns);
		excel.setKeyColumns(keyFields);
		excel.read();

		noRows = excel.lenght();
		assertEquals(noRowsLimit, noRows);

		String key = excel.getKeyValue(1);
		assertEquals("ACO/2023-12-01T00:00:00Z", key);

	}

	private WorkbookComparisonResult compareTables(Path pOriginalMasterFilePath, Path pClientFilePath,
			List<String> keyFields) throws IOException {
		ExcelWorkbook excel1, excel2;
		WorkbookComparisonResult compareResult;

		excel1 = new ExcelWorkbook(pOriginalMasterFilePath.toString());
		excel1.setKeyColumns(keyFields);

		excel1.read();

		excel2 = new ExcelWorkbook(pClientFilePath.toString());
		excel2.setKeyColumns(keyFields);
		excel2.read();

		compareResult = excel1.compareTo(excel2);

		return compareResult;
	}

	@Test
	void testCompareTo() throws IOException, ConfigurationException {
		List<String> keyFields = List.of("Name", "Firstname");
		Path originalMasterFilePath = resDir.resolve("CompareMasterOrig.xlsx");
		Path clientFilePath = resDir.resolve("CompareClient1.xlsx");

		WorkbookComparisonResult compareResult = this.compareTables(originalMasterFilePath, clientFilePath, keyFields);

	}

	@Test
	void testIntegrateDiff() throws IOException, ConfigurationException {
		List<String> keyFields = List.of("Name", "Firstname");
		Path originalMasterFilePath = resDir.resolve("CompareMasterOrig.xlsx");
		Path masterFilePath = resDir.resolve("CompareMaster.xlsx");
		Path clientFilePath = resDir.resolve("CompareClient1.xlsx");

		Files.copy(originalMasterFilePath, masterFilePath, StandardCopyOption.REPLACE_EXISTING);
		WorkbookComparisonResult compareResult = this.compareTables(masterFilePath, clientFilePath, keyFields);

		ExcelWorkbook integratedTable = (ExcelWorkbook) compareResult.integrateDifferencesIntoMaster();

		integratedTable.save();
	}
}
