import React from "react";
import Head from 'next/head';
import Image from 'next/image';
import moment from 'moment';
import 'moment/locale/ru';
import numeral from "numeral";
import cookie from 'cookie';

import { connect } from "react-redux";
import { withRouter } from 'next/router';
import { reduxWrapper } from '../../store';

import Header from '../components/Header';
import Footer from '../components/Footer';
import InnerMenu from "./components/InnerMenu";
import Company from "../components/Company";
import CalendarCellModal from "../components/Modal/calendar";

import { getCalendar } from '../../actions';
import { MatchMedia } from '../../utils/mediaqueries';
import AccountLayout from "../components/Layout/Account";

class CalendarPage extends React.Component 
{
	constructor(props)
	{
		super(props);
		this.state = {
			modalOpened: false,
			payments: null,
			periods: null, 
			selected_period: moment().format("YYYYMM"), 
			selected_payment: undefined, 
			current_week: parseInt(moment().format('ww'), 10), 
			selected_week: 0, 
			weeks_in_month: 1, 
			perweek: MatchMedia() === "mobile" ? true : false, 
		};
	}

	static getDerivedStateFromProps(nextProps, prevState)
	{
		return {
			company: nextProps.company, 
			payments: nextProps.payments, 
			periods: nextProps.periods, 
		};
	}

	componentDidMount()
	{
		const date_from = moment().startOf("month").subtract(7, 'day').toDate();
		const date_to = moment().endOf("month").add(7, 'day').toDate();

		var clonedMoment = moment();
		var first = clonedMoment.startOf('month').week();
		var last = clonedMoment.endOf('month').week();
		if( first > last) { last = first + last; }
		let mw = last - first + 1;
		const nwsd = moment().endOf("month").add(1, "day").format("e");

		if(nwsd !== 0) { mw = mw - 1; }
		this.setState({ weeks_in_month: mw });

		getCalendar({ dispatch: this.props.dispatch, date_from, date_to }).then().catch();
	}

	toggleModal = () => 
	{
		this.setState({
			modalOpened: !this.state.modalOpened
		})
	}

	getPayments = (date) => 
	{
		const { payments } = this.state;

		for(let i in payments)
		{
			if(payments[i].date === date)
			{
				return payments[i];
			}
		}
		return undefined;
	}

	_handle_onDayClick = (day) => 
	{
		this.setState({ selected_payment: day.payment });
		this.toggleModal();
	}
	
	_handle_onChangePeriod = (period, new_selected_week) => 
	{
		var clonedMoment = moment(period, "YYYYMM");
		var first = clonedMoment.startOf('month').week();
		var last = clonedMoment.endOf('month').week();
		if( first > last) { last = first + last; }
		let mw = last - first + 1;

		const ld = parseInt(moment(period, "YYYYMM").endOf("month").format("e"), 10);
		if(ld !== 6) { mw = mw - 1; }

		this.setState({ selected_period: period, weeks_in_month: mw, selected_week: new_selected_week}, () => 
		{
			const date_from = moment(period, "YYYYMM").startOf("month").subtract(7, 'day').toDate();
			const date_to = moment(period, "YYYYMM").endOf("month").add(7, 'day').toDate();

			getCalendar({ dispatch: this.props.dispatch, date_from, date_to }).then().catch();	
		});
	}

	_handle_onWeek_prev = () => 
	{
		const { selected_period, selected_week, } = this.state;

		if(selected_week === 0)
		{
			var clonedMoment = moment(selected_period, "YYYYMM").subtract(1, "month");
			var first = clonedMoment.startOf('month').week();
			var last = clonedMoment.endOf('month').week();
			if( first > last) { last = first + last; }
			let mw = last - first + 1;

			const ld = parseInt(clonedMoment.endOf("month").format("e"), 10);
			if(ld !== 6) { mw = mw - 1; }

			const new_selected_week = mw - 1;
			const prev_period = clonedMoment.format("YYYYMM");

			this._handle_onChangePeriod(prev_period, new_selected_week);
		}
		else
		{
			this.setState({ selected_week: parseInt(selected_week, 10) - 1 }, () => 
			{
			});
		}
	}

	_getWeekToSwitch = () => 
	{
		const { selected_period, selected_week, weeks_in_month } = this.state;
	} 

	_handle_onWeek_next = () => 
	{
		const { selected_period, selected_week, weeks_in_month } = this.state;
		const next_week = selected_week + 1;

		if(next_week === weeks_in_month)
		{
			const next_period = moment(selected_period, "YYYYMM").add(1, "month").format("YYYYMM");
			this._handle_onChangePeriod(next_period, 0);
		}
		else
		{
			this.setState({ selected_week: next_week }, () => 
			{
			});
		}
	}

	render()
	{
		const { selected_period, selected_payment, periods, payments, current_week, selected_week, perweek, weeks_in_month } = this.state;
		if(payments === null) { return null; }

		let month = moment(selected_period, "YYYYMM").format("M") - 1;

		const dates = [];
		const date_sm = moment(selected_period, 'YYYYMM').startOf("month");
		const date_em = moment(selected_period, 'YYYYMM').endOf("month");

		let date_s = null;
		if(date_sm.clone().isoWeekday() !== 1)
		{ date_s = date_sm.clone().subtract(date_sm.clone().isoWeekday() - 1, "days"); }
		else
		{ date_s = date_sm; }

		let date_e = null;
		if(date_em.day() !== 0)
		{ date_e = date_em.add(7 - date_em.day(), "days"); }
		else
		{ date_e = date_em; }

		const date = moment();

		let d = date_s;
		let payment = this.getPayments(date_s.format("YYYY-MM-DD"));
		dates.push({
			date: date_s.clone(), 
			payment: payment, 
		});

		while(d.add(1, 'days').diff(date_e) < 0) 
		{
			dates.push({
				date: d.clone(), 
			});
		}

		for(let i in dates)
		{
			dates[i].payment = this.getPayments(dates[i].date.format("YYYY-MM-DD"));
		}

		const dow = date.day();
		const weeks = dates.reduce(function(result, value, index, array) {
			if (index % 7 === 0)
			  result.push(array.slice(index, index +7));
			return result;
		}, []);

		let render_weeks = [];
		if(perweek)
		{
			render_weeks = weeks.slice(selected_week, weeks_in_month);
		}
		else
		{
			render_weeks = weeks;
		}

		const periods_list = Object.values(periods);

		return (
			<React.Fragment>
				<Head>
					<title>ЛК Эволюция автолизинга</title>
					<meta
						name="description"
						content="ЛК Эволюция автолизинга"
					/>
				</Head>
				<Header { ...this.props }/>
				<AccountLayout>
					<div className="title_wrapper">
						<div className="left">
							{/*[{ perweek ? 1 : 0 }, { current_week }, { selected_week }, { weeks_in_month }]*/}
							<h1 className="section_title">Календарь оплат</h1>
						</div>
						<Company { ...this.props }/>
					</div>
					<div className="aside_container about">
						<InnerMenu { ...this.props }/>
						<article>
							<div className="calendar_wrapper">
								<div className="form_field">
									{ periods_list.length > 0 && (
										<select id="calendar_month" value={ periods_list.indexOf(selected_period) < 0 ? periods_list[periods_list.length - 1] : selected_period } onChange={ (event) => this._handle_onChangePeriod(event.target.value, 0) }>
											{ periods !== null && periods_list.map((period, index) => (
													<option key={ index } value={ period }>{ moment(period, "YYYYMM").format('MMMM YYYY') }</option>
												)) }
										</select>
									) }
								</div>
								<div className="calendar_nav">
									<button onClick={ () => this._handle_onWeek_prev() } disabled={ moment(selected_period, "YYYYMM").add(selected_week * 7, "day") <= moment(periods_list[0], "YYYYMM") ? true : false }>Предыдущая неделя</button>
									<button onClick={ () => this._handle_onWeek_next() } disabled={ moment(selected_period, "YYYYMM").add(selected_week * 7, "day") >= moment(periods_list[periods_list.length - 1], "YYYYMM").add(1, "month") ? true : false }>Следующая неделя</button>
								</div>
								<div className="calendar_grid">
									<div className="grid_header">
										<div className="grid_cell">Пн</div>
										<div className="grid_cell">Вт</div>
										<div className="grid_cell">Ср</div>
										<div className="grid_cell">Чт</div>
										<div className="grid_cell">Пт</div>
										<div className="grid_cell">Сб</div>
										<div className="grid_cell">Вс</div>
									</div>
									<div className="grid_body">
										{ render_weeks.map((week, week_index) => 
										{
											return (
												<div className={week_index == 0 ? "grid_week active" : "grid_week"} key={"week_" + week_index}>
													{ week.map((day, index) => {
														if(day.payment)
														{
															return (
																<div key={ index } style={{ cursor: "pointer" }} className={`grid_cell payment ${ !perweek && day.date.month() !== month ? 'disabled' : '' } ${ day.date.format("YYYYMMDD") === moment().format("YYYYMMDD") ? 'current' : '' } `} onClick={ () => this._handle_onDayClick(day) }>
																	<div className="cell_header">
																		<p><span>{ day.date.format("DD") }</span> { day.date.format("MMM").toLocaleLowerCase() } <span className="year">{ day.date.format("Y").toLocaleLowerCase() }</span></p>
																	</div>
																	<div className="cell_body">{ day.payment && (
																		<p>
																			Общий платеж
																			<span style={ day.payment.total > 1000000 ? { fontSize: '14px', whiteSpace: "nowrap" } : { whiteSpace: "nowrap" }}>{ numeral(day.payment.total).format(' ., ') }&nbsp;₽</span>
																		</p>
																	)}
																	</div>
																</div>
															)
														}
														return (
															<div key={ index } className={`grid_cell ${ !perweek && day.date.month() !== month ? 'disabled' : '' } ${ day.date.format("YYYYMMDD") === moment().format("YYYYMMDD") ? 'current' : '' } `}>
																<div className="cell_header">
																	<p><span>{ day.date.format("DD") }</span> { day.date.format("MMM").toLocaleLowerCase() } <span className="year">{ day.date.format("Y").toLocaleLowerCase() }</span></p>
																</div>
															</div>
														)
													}) }
												</div>
											)
										}) }
									</div>
								</div>
							</div>
						</article>
					</div>
				</AccountLayout>
				<CalendarCellModal open={ this.state.modalOpened } selected_payment={ selected_payment } close={ () => this.toggleModal() }/>
				<Footer/>
			</React.Fragment>
		)
	}
}

function mapStateToProps(state, ownProps)
{
	return {
		company: state.company, 
		payments: state.calendar.payments, 
		periods: state.calendar.periods, 
	}
}

export const getServerSideProps = reduxWrapper.getServerSideProps(store => 
	async ({ req, res, query }) => 
	{
		let props = {};

		if(req.headers.cookie !== undefined)
		{
			const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : "");

			if(cookies.jwt === undefined || cookies.jwt === null)
			{
				res.statusCode = 302;
				res.setHeader('Location', `/login`);
			}
			else
			{
				const tokenValid = true;
				if(!tokenValid)
				{
					res.statusCode = 302;
					res.setHeader('Location', `/login`);
				}
			}
		}
		else
		{
			res.statusCode = 302;
			res.setHeader('Location', `/login`);
		}
	
		return { props: props };
	}
);

export default withRouter(connect(mapStateToProps)(CalendarPage));