# Copyright (c) 2020, JINGROW
# For license information, please see license.txt

"""
Suspend Sites of defaulter accounts.

This module deals with suspending sites of defaulters.

Defaulters are identified based on the following conditions:
- Is not a free account
- Is not a Legacy Partner account with payment mode as Partner Credits
- Has at least one unpaid invoice
- Has an active site

The `execute` method is the main method which is run by the scheduler on every day of the month.
"""

import jingrow
from jingrow.utils import add_days, get_first_day, get_last_day, getdate

from jcloud.utils import log_error


def execute():
	today = getdate()
	first_day_of_month = get_first_day(today)
	nineth_day_of_month = add_days(first_day_of_month, 8)

	if today >= first_day_of_month and today <= nineth_day_of_month:
		return

	teams_with_unpaid_invoices = get_teams_with_unpaid_invoices()

	for d in teams_with_unpaid_invoices[:30]:
		team = jingrow.get_pg("Team", d.team)

		# suspend sites
		suspend_sites_and_send_email(team)


def suspend_sites_and_send_email(team):
	try:
		sites = team.suspend_sites(reason="Unpaid Invoices")
		jingrow.db.commit()
	except Exception:
		log_error(
			f"Error while suspending sites for team {team.name}",
			traceback=jingrow.get_traceback(),
		)
		jingrow.db.rollback()
	# send email
	if sites:
		email = team.user
		jingrow.sendmail(
			recipients=email,
			subject="Your sites have been suspended on Jingrow",
			template="suspended_sites",
			args={
				"subject": "Your sites have been suspended on Jingrow",
				"sites": sites,
			},
		)


def get_teams_with_unpaid_invoices():
	"""Find out teams which has active sites and unpaid invoices and not a free account"""
	today = getdate()
	# last day of previous month
	last_day = get_last_day(jingrow.utils.add_months(today, -1))

	plan = jingrow.qb.PageType("Site Plan")
	query = (
		jingrow.qb.from_(plan)
		.select(plan.name)
		.where((plan.enabled == 1) & (plan.is_jingrow_plan == 1))
	).run(as_dict=True)
	jingrow_plans = [d.name for d in query]

	invoice = jingrow.qb.PageType("Invoice")
	team = jingrow.qb.PageType("Team")
	site = jingrow.qb.PageType("Site")

	query = (
		jingrow.qb.from_(invoice)
		.inner_join(team)
		.on(invoice.team == team.name)
		.inner_join(site)
		.on(site.team == team.name)
		.where(
			(site.status).isin(["Active", "Inactive"])
			& (team.enabled == 1)
			& (team.free_account == 0)
			& (invoice.status == "Unpaid")
			& (invoice.pagestatus < 2)
			& (invoice.type == "Subscription")
			& (site.free == 0)
			& (site.plan).notin(jingrow_plans)
			& (invoice.period_end <= last_day)
		)
		.select(invoice.team)
		.distinct()
	)

	first_day = get_first_day(today)
	two_weeks = add_days(first_day, 14) # 15th day of the month
	if today < two_weeks:
		query = query.where(team.jerp_partner == 0)

	return query.run(as_dict=True)
