from enum import Enum

from django.db.models import Avg, Count, Max, Min, Sum
from django.db.models.functions import (
    TruncDay,
    TruncMonth,
    TruncQuarter,
    TruncWeek,
    TruncYear,
)

REVERSE_FOREIGN_KEY_DELIMITER_COMMA = 1
REVERSE_FOREIGN_KEY_DELIMITER_SEMICOLON = 2
REVERSE_FOREIGN_KEY_DELIMITER_PIPE = 3
REVERSE_FOREIGN_KEY_DELIMITER_DASH = 4
REVERSE_FOREIGN_KEY_DELIMITER_SPACE = 5

REVERSE_FOREIGN_KEY_DELIMITER_CHOICES = [
    (REVERSE_FOREIGN_KEY_DELIMITER_COMMA, ', '),
    (REVERSE_FOREIGN_KEY_DELIMITER_SEMICOLON, ';'),
    (REVERSE_FOREIGN_KEY_DELIMITER_PIPE, ' | '),
    (REVERSE_FOREIGN_KEY_DELIMITER_DASH, ' - '),
    (REVERSE_FOREIGN_KEY_DELIMITER_SPACE, 'Space'),
]

REVERSE_FOREIGN_KEY_DELIMITER_VALUES = {
    REVERSE_FOREIGN_KEY_DELIMITER_COMMA: ', ',
    REVERSE_FOREIGN_KEY_DELIMITER_SEMICOLON: ';',
    REVERSE_FOREIGN_KEY_DELIMITER_PIPE: ' | ',
    REVERSE_FOREIGN_KEY_DELIMITER_DASH: ' - ',
    REVERSE_FOREIGN_KEY_DELIMITER_SPACE: ' ',
}

ANNOTATION_VALUE_YEAR = 1
ANNOTATION_VALUE_QUARTER = 2
ANNOTATION_VALUE_MONTH = 3
ANNOTATION_VALUE_WEEK = 4
ANNOTATION_VALUE_DAY = 5
ANNOTATION_VALUE_FINANCIAL_QUARTER = 6  # not used yet

ANNOTATION_VALUE_CHOICES = [
    (ANNOTATION_VALUE_YEAR, 'Year'),
    (ANNOTATION_VALUE_QUARTER, 'Quarter'),
    # (ANNOTATION_VALUE_FINANCIAL_QUARTER, 'Financial Quarter'),
    (ANNOTATION_VALUE_MONTH, 'Month'),
    (ANNOTATION_VALUE_WEEK, 'Week'),
    (ANNOTATION_VALUE_DAY, 'Day'),
]

ANNOTATION_VALUE_FUNCTIONS = {
    ANNOTATION_VALUE_YEAR: TruncYear,
    ANNOTATION_VALUE_QUARTER: TruncQuarter,
    ANNOTATION_VALUE_MONTH: TruncMonth,
    ANNOTATION_VALUE_WEEK: TruncWeek,
    ANNOTATION_VALUE_DAY: TruncDay,
}

REVERSE_FOREIGN_KEY_ANNOTATION_BOOLEAN_XOR = 1
REVERSE_FOREIGN_KEY_ANNOTATION_BOOLEAN_AND = 2
REVERSE_FOREIGN_KEY_ANNOTATION_BOOLEAN_ARRAY = 3

REVERSE_FOREIGN_KEY_ANNOTATION_BOOLEAN_CHOICES = [
    (REVERSE_FOREIGN_KEY_ANNOTATION_BOOLEAN_XOR, 'XOR'),
    (REVERSE_FOREIGN_KEY_ANNOTATION_BOOLEAN_AND, 'And'),
    (REVERSE_FOREIGN_KEY_ANNOTATION_BOOLEAN_ARRAY, 'Array'),
]

REVERSE_FOREIGN_KEY_ANNOTATION_DATE_ARRAY = 1
REVERSE_FOREIGN_KEY_ANNOTATION_DATE_MIN = 2
REVERSE_FOREIGN_KEY_ANNOTATION_DATE_MAX = 3

REVERSE_FOREIGN_KEY_ANNOTATION_DATE_CHOICES = [
    (REVERSE_FOREIGN_KEY_ANNOTATION_DATE_ARRAY, 'Array'),
    (REVERSE_FOREIGN_KEY_ANNOTATION_DATE_MIN, 'Min'),
    (REVERSE_FOREIGN_KEY_ANNOTATION_DATE_MAX, 'Max'),
]

ANNOTATION_CHART_SCALE = {
    ANNOTATION_VALUE_YEAR: 'year',
    ANNOTATION_VALUE_QUARTER: 'quarter',
    ANNOTATION_VALUE_MONTH: 'month',
    ANNOTATION_VALUE_WEEK: 'week',
    ANNOTATION_VALUE_DAY: 'day',
}

GENERATE_SERIES_INTERVALS = {
    ANNOTATION_VALUE_YEAR: '1 year',
    ANNOTATION_VALUE_QUARTER: '3 month',
    ANNOTATION_VALUE_MONTH: '1 month',
    ANNOTATION_VALUE_WEEK: '1 week',
    ANNOTATION_VALUE_DAY: '1 day',
}

ANNOTATION_CHOICE_NA = 0
ANNOTATION_CHOICE_SUM = 1
ANNOTATION_CHOICE_MAXIMUM = 2
ANNOTATION_CHOICE_MINIMUM = 3
ANNOTATION_CHOICE_COUNT = 4
ANNOTATION_CHOICE_AVERAGE_SUM_FROM_COUNT = 5

ANNOTATIONS_CHOICES = [
    (ANNOTATION_CHOICE_SUM, 'Sum'),
    (ANNOTATION_CHOICE_MAXIMUM, 'Maximum'),
    (ANNOTATION_CHOICE_MINIMUM, 'Minimum'),
    (ANNOTATION_CHOICE_COUNT, 'Count'),
    (ANNOTATION_CHOICE_AVERAGE_SUM_FROM_COUNT, 'Average Sum from Count'),
]

ANNOTATION_FUNCTIONS = {
    ANNOTATION_CHOICE_SUM: Sum,
    ANNOTATION_CHOICE_MAXIMUM: Max,
    ANNOTATION_CHOICE_MINIMUM: Min,
    ANNOTATION_CHOICE_COUNT: Count,
    ANNOTATION_CHOICE_AVERAGE_SUM_FROM_COUNT: Avg,
}

AGGREGATE_CLASSES = (Sum, Avg, Max, Min, Count)

ALIGNMENT_CHOICE_LEFT = 0
ALIGNMENT_CHOICE_CENTRE = 1
ALIGNMENT_CHOICE_RIGHT = 2

ALIGNMENT_CHOICES = [
    (ALIGNMENT_CHOICE_LEFT, 'Left'),
    (ALIGNMENT_CHOICE_CENTRE, 'Centre'),
    (ALIGNMENT_CHOICE_RIGHT, 'Right'),
]

ALIGNMENT_CLASS = {
    ALIGNMENT_CHOICE_LEFT: '',
    ALIGNMENT_CHOICE_CENTRE: 'dt-center',
    ALIGNMENT_CHOICE_RIGHT: 'dt-right',
}

DATE_FORMAT_TYPE_DD_MM_YY_SLASH = 1
DATE_FORMAT_TYPE_DD_MM_YYYY_SLASH = 2
DATE_FORMAT_TYPE_MM_DD_YY_SLASH = 3
DATE_FORMAT_TYPE_MM_DD_YYYY_SLASH = 4
DATE_FORMAT_TYPE_DD_MM_YY_DASH = 5
DATE_FORMAT_TYPE_DD_MM_YYYY_DASH = 6
DATE_FORMAT_TYPE_MM_DD_YY_DASH = 7
DATE_FORMAT_TYPE_MM_DD_YYYY_DASH = 8
DATE_FORMAT_TYPE_WORDS_MM_DD_YYYY = 9
DATE_FORMAT_TYPE_WORDS_DD_MM_YYYY = 10
DATE_FORMAT_TYPE_SHORT_WORDS_MM_DD_YYYY = 11
DATE_FORMAT_TYPE_SHORT_WORDS_DD_MM_YYYY = 12
DATE_FORMAT_TYPE_YYYY = 13
DATE_FORMAT_TYPE_YY = 14
DATE_FORMAT_TYPE_MM_YY = 15
DATE_FORMAT_TYPE_MM_YYYY = 16
DATE_FORMAT_TYPE_WORDS_MM_YY = 17
DATE_FORMAT_TYPE_WORDS_MM_YYYY = 18
DATE_FORMAT_TYPE_SHORT_WORDS_MM_YY = 19
DATE_FORMAT_TYPE_SHORT_WORDS_MM_YYYY = 20
DATE_FORMAT_TYPE_MM = 21
DATE_FORMAT_TYPE_WORDS_MM = 22
DATE_FORMAT_TYPE_SHORT_WORDS_MM = 23
DATE_FORMAT_TYPE_WW = 24
DATE_FORMAT_TYPE_WW_YYYY_DASH = 25
DATE_FORMAT_TYPE_WW_YY_DASH = 26
DATE_FORMAT_TYPE_YYYY_MM = 27


DATE_FORMAT_TYPES_DJANGO_FORMAT = {
    DATE_FORMAT_TYPE_DD_MM_YY_SLASH: '%d/%m/%y',
    DATE_FORMAT_TYPE_DD_MM_YYYY_SLASH: '%d/%m/%Y',
    DATE_FORMAT_TYPE_MM_DD_YY_SLASH: '%m/%d/%y',
    DATE_FORMAT_TYPE_MM_DD_YYYY_SLASH: '%m/%d/%Y',
    DATE_FORMAT_TYPE_DD_MM_YY_DASH: '%d-%m-%y',
    DATE_FORMAT_TYPE_DD_MM_YYYY_DASH: '%d-%m-%Y',
    DATE_FORMAT_TYPE_MM_DD_YY_DASH: '%m-%d-%y',
    DATE_FORMAT_TYPE_MM_DD_YYYY_DASH: '%m-%d-%Y',
    DATE_FORMAT_TYPE_WORDS_MM_DD_YYYY: '%B %d %Y',
    DATE_FORMAT_TYPE_WORDS_DD_MM_YYYY: '%d %B %Y',
    DATE_FORMAT_TYPE_SHORT_WORDS_MM_DD_YYYY: '%b %d %Y',
    DATE_FORMAT_TYPE_SHORT_WORDS_DD_MM_YYYY: '%d %b %Y',
    DATE_FORMAT_TYPE_YYYY: '%Y',
    DATE_FORMAT_TYPE_YY: '%y',
    DATE_FORMAT_TYPE_MM_YY: '%m %y',
    DATE_FORMAT_TYPE_YYYY_MM: '%Y %m',
    DATE_FORMAT_TYPE_MM_YYYY: '%m %Y',
    DATE_FORMAT_TYPE_WORDS_MM_YY: '%B %y',
    DATE_FORMAT_TYPE_WORDS_MM_YYYY: '%B %Y',
    DATE_FORMAT_TYPE_SHORT_WORDS_MM_YY: '%b %y',
    DATE_FORMAT_TYPE_SHORT_WORDS_MM_YYYY: '%b %Y',
    DATE_FORMAT_TYPE_MM: '%m',
    DATE_FORMAT_TYPE_WORDS_MM: '%B',
    DATE_FORMAT_TYPE_SHORT_WORDS_MM: '%b',
    DATE_FORMAT_TYPE_WW: '%W',
    DATE_FORMAT_TYPE_WW_YYYY_DASH: '%W-%Y',
    DATE_FORMAT_TYPE_WW_YY_DASH: '%W-%y',
}

DATE_FORMAT_TYPES = [
    (DATE_FORMAT_TYPE_DD_MM_YY_SLASH, 'dd/mm/yy'),
    (DATE_FORMAT_TYPE_DD_MM_YYYY_SLASH, 'dd/mm/yyyy'),
    (DATE_FORMAT_TYPE_MM_DD_YY_SLASH, 'mm/dd/yy'),
    (DATE_FORMAT_TYPE_MM_DD_YYYY_SLASH, 'mm/dd/yyyy'),
    (DATE_FORMAT_TYPE_DD_MM_YY_DASH, 'dd-mm-yy'),
    (DATE_FORMAT_TYPE_DD_MM_YYYY_DASH, 'dd-mm-yyyy'),
    (DATE_FORMAT_TYPE_MM_DD_YY_DASH, 'mm-dd-yy'),
    (DATE_FORMAT_TYPE_MM_DD_YYYY_DASH, 'mm-dd-yyyy'),
    (DATE_FORMAT_TYPE_WORDS_MM_DD_YYYY, 'MM d yyyy'),
    (DATE_FORMAT_TYPE_WORDS_DD_MM_YYYY, 'd MM yyyy'),
    (DATE_FORMAT_TYPE_SHORT_WORDS_MM_DD_YYYY, 'M d yyyy'),
    (DATE_FORMAT_TYPE_SHORT_WORDS_DD_MM_YYYY, 'd M yyyy'),
    (DATE_FORMAT_TYPE_YYYY, 'yyyy'),
    (DATE_FORMAT_TYPE_YY, 'yy'),
    (DATE_FORMAT_TYPE_MM_YY, 'mm yy'),
    (DATE_FORMAT_TYPE_MM_YYYY, 'mm yyyy'),
    (DATE_FORMAT_TYPE_YYYY_MM, 'yyyy mm'),
    (DATE_FORMAT_TYPE_WORDS_MM_YY, 'MM yy'),
    (DATE_FORMAT_TYPE_WORDS_MM_YYYY, 'MM yyyy'),
    (DATE_FORMAT_TYPE_SHORT_WORDS_MM_YY, 'b yy'),
    (DATE_FORMAT_TYPE_SHORT_WORDS_MM_YYYY, 'b yyyy'),
    (DATE_FORMAT_TYPE_MM, 'mm'),
    (DATE_FORMAT_TYPE_WORDS_MM, 'MM'),
    (DATE_FORMAT_TYPE_SHORT_WORDS_MM, 'd'),
    (DATE_FORMAT_TYPE_WW, 'WW'),
    (DATE_FORMAT_TYPE_WW_YYYY_DASH, 'WW-YYYY'),
    (DATE_FORMAT_TYPE_WW_YY_DASH, 'WW-YY'),
]

DISPLAY_OPTION_NONE = 0
DISPLAY_OPTION_1_PER_ROW = 1
DISPLAY_OPTION_2_PER_ROW = 2
DISPLAY_OPTION_3_PER_ROW = 3
DISPLAY_OPTION_4_PER_ROW = 4

DISPLAY_OPTION_CHOICES = [
    (DISPLAY_OPTION_NONE, 'None/Default'),
    (DISPLAY_OPTION_1_PER_ROW, '1 Report per Row'),
    (DISPLAY_OPTION_2_PER_ROW, '2 Reports per Row'),
    (DISPLAY_OPTION_3_PER_ROW, '3 Reports per Row'),
    (DISPLAY_OPTION_4_PER_ROW, '4 Reports per Row'),
]

DISPLAY_OPTION_CLASSES = {
    DISPLAY_OPTION_1_PER_ROW: ' col-12',
    DISPLAY_OPTION_2_PER_ROW: ' col-12 col-md-12 col-lg-6',
    DISPLAY_OPTION_3_PER_ROW: ' col-12 col-md-12 col-lg-4',
    DISPLAY_OPTION_4_PER_ROW: ' col-12 col-md-12 col-lg-3',
}

DEFAULT_DATE_FORMAT = {
    ANNOTATION_VALUE_YEAR: DATE_FORMAT_TYPE_YYYY,
    ANNOTATION_VALUE_QUARTER: DATE_FORMAT_TYPE_WORDS_MM_YY,
    ANNOTATION_VALUE_MONTH: DATE_FORMAT_TYPE_WORDS_MM_YY,
    ANNOTATION_VALUE_WEEK: DATE_FORMAT_TYPE_WW_YY_DASH,
    ANNOTATION_VALUE_DAY: DATE_FORMAT_TYPE_DD_MM_YY_SLASH,
}

CALENDAR_VIEW_TYPE_MONTH = 1
CALENDAR_VIEW_TYPE_GRID_WEEK = 2
CALENDAR_VIEW_TYPE_LIST_WEEK = 3
CALENDAR_VIEW_TYPE_DAY = 4
CALENDAR_VIEW_TYPE_YEAR = 5

CALENDAR_VIEW_TYPE_CHOICES = (
    (CALENDAR_VIEW_TYPE_MONTH, 'Month'),
    (CALENDAR_VIEW_TYPE_GRID_WEEK, 'Grid Week'),
    (CALENDAR_VIEW_TYPE_LIST_WEEK, 'List Week'),
    (CALENDAR_VIEW_TYPE_DAY, 'Day'),
    (CALENDAR_VIEW_TYPE_YEAR, 'Year'),
)


class FieldType(Enum):
    NULL_FIELD = 1
    ABSTRACT_USER = 2
    FILTER_FOREIGN_KEY = 3
    STRING = 4
    NUMBER = 5
    BOOLEAN = 6
    DATE = 7
    MANY_TO_MANY = 8
