import {chromium} from 'playwright';
import {Temporal} from '@js-temporal/polyfill';
import {createWriteStream, writeFileSync, readFileSync} from 'fs';
import dotenv from 'dotenv';
dotenv.config();
const endDate = Temporal.Now.plainDateISO().subtract({days: 1});
let startDate = endDate.subtract({years: 1}).with({ day: 1 });
try {
	startDate = Temporal.PlainDate.from(readFileSync('lastDate', 'utf8')).add({days: 1});
} catch(e) {}
if(Temporal.Duration.compare(startDate.until(endDate), Temporal.Duration.from({days: 0})) === 1) {
	const browser = await chromium.launch({headless: false});
	const context = await browser.newContext();
	const page = await context.newPage();
	await page.route('**/*', route => {
		const f = route.request().resourceType();
		if(f === 'document' || f === 'script' || f === 'xhr') {
			route.continue();
		} else {
			route.abort();
		}
	});
	await page.goto('https://selfserve.publicmobile.ca');
	await page.fill('#FullContent_ContentBottom_LoginControl_UserName', process.env.EMAIL);
	await page.fill('#FullContent_ContentBottom_LoginControl_Password', process.env.PASSPHRASE);
	await page.click('#FullContent_ContentBottom_LoginControl_LoginButton');
	await page.goto('https://selfserve.publicmobile.ca/Overview/plan-and-Add-ons/call-history/');
	await page.check('#UseDateRangeRadioButton');
	await page.fill('#startdate', startDate.toString());
	await page.fill('#enddate', endDate.toString());
	await Promise.all([
		page.waitForNavigation(),
		page.click('#FullContent_DashboardContent_ViewCallHistoryButton')
	]);
	await Promise.all([
		page.waitForResponse(r => r.url() === 'https://selfserve.publicmobile.ca/Overview/plan-and-Add-ons/call-history/'),
		page.click('#FullContent_DashboardContent_gvCallHistory > tbody > tr.gvCallHistoryHeader > th.gridViewTDHideShowHeader > a')
	]);
	let shit = [];
	const h1 = (await page.$eval('.gvCallHistoryHeader', e => e.innerText.split('\t'))).join() + '\n';
	while(true) {
		shit = shit.concat(await page.$eval('#FullContent_DashboardContent_gvCallHistory > tbody', x => {
			x = x.children;
			let out = [];
			for(let i = 1; i < x.length - 1; ++i) {
				let t = x[i].innerText.split('\t');
				for(let j = 0; j < t.length; ++j) {
					t[j] = t[j].trim();
				}
				out.push(t);
			}
			return out;
		}));
		if(await page.getAttribute('#FullContent_DashboardContent_gvCallHistory_gvPagerTemplate_pagerNextPage', 'href') === null) {
			break;
		} else {
			await Promise.all([
				page.waitForResponse(r => r.url() === 'https://selfserve.publicmobile.ca/Overview/plan-and-Add-ons/call-history/'),
				page.click('#FullContent_DashboardContent_gvCallHistory_gvPagerTemplate_pagerNextPage')
			]);
		}
	}
	await page.goto('https://selfserve.publicmobile.ca/Overview/payment/Payment-History/');
	await page.check('#UseDateRangeRadioButton');
	await page.fill('#startdate', startDate.toString());
	await page.fill('#enddate', endDate.toString());
	await Promise.all([
		page.waitForNavigation(),
		page.click('#FullContent_DashboardContent_ViewTransactionHistoryButton')
	]);
	let shit2 = [];
	writeFileSync('payment.csv', (await page.$eval('.gvTransactionHistoryHeader1', e => e.innerText.split('\t'))).join() + '\n', {flag: 'wx'});
	while(true) {
		shit2 = shit2.concat(await page.$eval('#FullContent_DashboardContent_gvTransactionHistory > tbody', x => {
			x = x.children;
			let out = [];
			for(let i = 1; i < x.length - 1; ++i) {
				let t = x[i].innerText.split('\t');
				for(let j = 0; j < t.length; ++j) {
					t[j] = t[j].trim();
				}
				out.push(t);
			}
			return out;
		}));
		if(await page.getAttribute('#FullContent_DashboardContent_gvTransactionHistory_gvPagerTemplate_pagerNextPage', 'href') === null) {
			break;
		} else {
			await Promise.all([
				page.waitForResponse(r => r.url() === 'https://selfserve.publicmobile.ca/Overview/payment/Payment-History/'),
				page.click('#FullContent_DashboardContent_gvTransactionHistory_gvPagerTemplate_pagerNextPage')
			]);
		}
	}
	await browser.close();
	let usageStreams = new Map();
	for(let i = shit.length - 1; i >= 0; --i) {
		shit[i][0] = shit[i][0].replace(/^(\d{2})\/(\d{2})\/(\d{4})/, "$3-$2-$1");
		let ym = shit[i][0].substring(0, 7);
		if(shit[i][8] === 'MB') {
			ym = shit[i][8] + '-' + ym;
		}
		if(!usageStreams.has(ym)) {
			writeFileSync(`usage-${ym}.csv`, h1, {flag: 'wx'});
			usageStreams.set(ym, [createWriteStream(`usage-${ym}.csv`, {flags: 'a'}), []]);
		}
		usageStreams.get(ym)[1].push(shit[i]);
	}
	usageStreams.forEach(v => {
		function datehour(s) {
			let fuck = s.split(/\s+/);
			return [fuck[0], Number(fuck[1].split(':')[0])];
		}
		function dumb(temp, idx) {
			if(temp[1] === 12) {
				v[1][idx][0] = v[1][idx][0].replace('12:', '00:');
			} else {
				console.error('what the fuck', temp, idx, v[1][idx]);
			}
		}
		function gay(i) {
			switch(drops.length) {
				case 0:
					break;
				case 2:
					let idx = drops[0] - 1;
					let original = datehour(v[1][idx][0]);
					let temp = original;
					dumb(temp, idx);
					while(--idx >= 0 && original[0] === (temp = datehour(v[1][idx][0]))[0]) {
						dumb(temp, idx);
					}
				case 1:
					for(let j = drops[drops.length - 1]; j < i; ++j) {
						v[1][j][0] = v[1][j][0].replace(/(\d{1,2}):/, (match, p1) => Number(p1) + 12 + ':');
					}
					break;
				default:
					console.error('wtf', v[1][i], i, drops);
			}
			drops = [];
		}
		let dt = datehour(v[1][0][0]);
		let drops = [];
		for(let i = 1; i < v[1].length; ++i) {
			let dtt = datehour(v[1][i][0]);
			if(dtt[0] === dt[0]) {//same day
				if(dtt[1] < dt[1]) {//new hour is less than (for example, 12 noon -> 1pm)
					drops.push(i);
				}
			} else {//different day
				gay(i);
			}
			dt = dtt;
		}
		gay(v[1].length);
		for(let i = 0; i < v[1].length; ++i) {
			v[1][i][0] = v[1][i][0].replace(/ (\d):/, " 0$1:");
			v[0].write(v[1][i].join() + '\n');
		}
		v[0].end();
	});
	let months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
	const stream2 = createWriteStream("payment.csv", {flags: 'a'});
	for(let i = shit2.length - 1; i >= 0; --i) {
		let date = shit2[i][0].split(/\s+/);
		date[1].replace(',', '');
		for(let j = 0; j < months.length; ++j) {
			if(months[j].startsWith(date[0].toLowerCase())) {
				date[0] = (j + 1 + '').padStart(2, '0');
				break;
			}
		}
		shit2[i][0] = `${date[2]}-${date[0]}-${date[1].padStart(2, '0')}`;
		stream2.write(shit2[i].join() + '\n');
	}
	stream2.end();
	writeFileSync('lastDate', endDate.toString());
} else {
	console.log('nothing to do');
	process.exit(0);
}