import arches.app.models.fields.i18n
import arches.app.utils.betterJSONSerializer
import django.db.models.deletion

from django.db import migrations, models


BOOLEAN_FACETS = [
    {
        "datatype": "boolean",
        "label": "is true",
        "operator": "IS_TRUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "boolean",
        "label": "is false",
        "operator": "IS_FALSE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "boolean",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "boolean",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

DATE_FACETS = [
    {
        "datatype": "date",
        "label": "=",
        "operator": "EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "date",
        "label": "!=",
        "operator": "NOT_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "date",
        "label": "<",
        "operator": "LESS_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__lt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "date",
        "label": ">",
        "operator": "GREATER_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__gt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "date",
        "label": "<=",
        "operator": "LESS_THAN_OR_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__lte",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "date",
        "label": ">=",
        "operator": "GREATER_THAN_OR_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__gte",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "date",
        "label": "is between",
        "operator": "BETWEEN",
        "arity": 2,
        "param_formats": ["{value0}", "{value1}"],
        "orm_template": "{col}__range",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "date",
        "label": "is not between",
        "operator": "NOT_BETWEEN",
        "arity": 2,
        "param_formats": ["{value0}", "{value1}"],
        "orm_template": "{col}__range",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "date",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "date",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

EDTF_FACETS = [
    {
        "datatype": "edtf",
        "label": "=",
        "operator": "EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "edtf",
        "label": "!=",
        "operator": "NOT_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "edtf",
        "label": "<",
        "operator": "LESS_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__lt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "edtf",
        "label": ">",
        "operator": "GREATER_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__gt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "edtf",
        "label": "<=",
        "operator": "LESS_THAN_OR_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__lte",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "edtf",
        "label": ">=",
        "operator": "GREATER_THAN_OR_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__gte",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "edtf",
        "label": "overlaps",
        "operator": "OVERLAPS",
        "arity": 2,
        "param_formats": ["{value0}", "{value1}"],
        "orm_template": "AND:{col_start}__lte:{p1};{col_end}__gte:{p0}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "edtf",
        "label": "is during",
        "operator": "DURING",
        "arity": 2,
        "param_formats": ["{value0}", "{value1}"],
        "orm_template": "AND:{col_start}__gte:{p0};{col_end}__lte:{p1}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "edtf",
        "label": "contains",
        "operator": "CONTAINS",
        "arity": 2,
        "param_formats": ["{value0}", "{value1}"],
        "orm_template": "AND:{col_start}__lte:{p0};{col_end}__gte:{p1}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "edtf",
        "label": "starts at",
        "operator": "STARTS_AT",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col_start}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "edtf",
        "label": "finishes at",
        "operator": "FINISHES_AT",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col_end}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "edtf",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "edtf",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

FILE_LIST_FACETS = [
    {
        "datatype": "file-list",
        "label": "size is greater than",
        "operator": "FILE_SIZE_GREATER_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__gt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "file-list",
        "label": "size is less than",
        "operator": "FILE_SIZE_LESS_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__lt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "file-list",
        "label": "size is between",
        "operator": "FILE_SIZE_BETWEEN",
        "arity": 2,
        "param_formats": ["{value0}", "{value1}"],
        "orm_template": "{col}__range",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "file-list",
        "label": "count is greater than",
        "operator": "FILE_COUNT_GREATER_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__gt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "file-list",
        "label": "count is less than",
        "operator": "FILE_COUNT_LESS_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__lt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "file-list",
        "label": "name is like",
        "operator": "FILE_NAME_LIKE",
        "arity": 1,
        "param_formats": ["%{value}%"],
        "orm_template": "{col}__icontains",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "file-list",
        "label": "extension equals",
        "operator": "FILE_EXTENSION_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__iexact",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "file-list",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "file-list",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

GEOJSON_FEATURE_COLLECTION_FACETS = [
    {
        "datatype": "geojson-feature-collection",
        "label": "contains a point",
        "operator": "GEO_CONTAINS_POINT",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__contains",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "geojson-feature-collection",
        "label": "contains a line",
        "operator": "GEO_CONTAINS_LINE",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__contains",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "geojson-feature-collection",
        "label": "contains a polygon",
        "operator": "GEO_CONTAINS_POLYGON",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__contains",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "geojson-feature-collection",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "geojson-feature-collection",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

NON_LOCALIZED_STRING_FACETS = [
    {
        "datatype": "non-localized-string",
        "label": "is like",
        "operator": "LIKE",
        "arity": 1,
        "param_formats": ["%{value}%"],
        "orm_template": "{col}__icontains",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "non-localized-string",
        "label": "is not like",
        "operator": "NOT_LIKE",
        "arity": 1,
        "param_formats": ["%{value}%"],
        "orm_template": "{col}__icontains",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "non-localized-string",
        "label": "starts with",
        "operator": "STARTS_WITH",
        "arity": 1,
        "param_formats": ["{value}%"],
        "orm_template": "{col}__istartswith",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "non-localized-string",
        "label": "ends with",
        "operator": "ENDS_WITH",
        "arity": 1,
        "param_formats": ["%{value}"],
        "orm_template": "{col}__iendswith",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "non-localized-string",
        "label": "equals",
        "operator": "EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__iexact",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "non-localized-string",
        "label": "does not equal",
        "operator": "NOT_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__iexact",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "non-localized-string",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "non-localized-string",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

NUMBER_FACETS = [
    {
        "datatype": "number",
        "label": "=",
        "operator": "EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "number",
        "label": "!=",
        "operator": "NOT_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "number",
        "label": "<",
        "operator": "LESS_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__lt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "number",
        "label": ">",
        "operator": "GREATER_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__gt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "number",
        "label": "<=",
        "operator": "LESS_THAN_OR_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__lte",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "number",
        "label": ">=",
        "operator": "GREATER_THAN_OR_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__gte",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "number",
        "label": "is between",
        "operator": "BETWEEN",
        "arity": 2,
        "param_formats": ["{value0}", "{value1}"],
        "orm_template": "{col}__range",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "number",
        "label": "is not between",
        "operator": "NOT_BETWEEN",
        "arity": 2,
        "param_formats": ["{value0}", "{value1}"],
        "orm_template": "{col}__range",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "number",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "number",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

REFERENCE_FACETS = [
    {
        "datatype": "reference",
        "label": "references any",
        "operator": "REFERENCES_ANY",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "{col}__in",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "reference",
        "label": "references all",
        "operator": "REFERENCES_ALL",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "HAVING_ALL:{col}:{values}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "reference",
        "label": "references only",
        "operator": "REFERENCES_ONLY",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "HAVING_ONLY:{col}:{values}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "reference",
        "label": "references none of",
        "operator": "REFERENCES_NONE_OF",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "{col}__in",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "reference",
        "label": "descendant of",
        "operator": "DESCENDANT_OF",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "{col}__in",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "reference",
        "label": "ancestor of",
        "operator": "ANCESTOR_OF",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "{col}__in",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "reference",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "reference",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

RESOURCE_INSTANCE_FACETS = [
    {
        "datatype": "resource-instance",
        "label": "references any",
        "operator": "REFERENCES_ANY",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "{col}__in",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "resource-instance",
        "label": "references all",
        "operator": "REFERENCES_ALL",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "AGG_SUPERSET:{col}:{p0}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "resource-instance",
        "label": "references only",
        "operator": "REFERENCES_ONLY",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "AGG_SET_EQUAL:{col}:{p0}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "resource-instance",
        "label": "references none of",
        "operator": "REFERENCES_NONE_OF",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "{col}__in",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "resource-instance",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "resource-instance",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

RESOURCE_INSTANCE_LIST_FACETS = [
    {
        "datatype": "resource-instance-list",
        "label": "references any",
        "operator": "REFERENCES_ANY",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "{col}__in",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "resource-instance-list",
        "label": "references all",
        "operator": "REFERENCES_ALL",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "AGG_SUPERSET:{col}:{p0}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "resource-instance-list",
        "label": "references only",
        "operator": "REFERENCES_ONLY",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "AGG_SET_EQUAL:{col}:{p0}",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "resource-instance-list",
        "label": "references none of",
        "operator": "REFERENCES_NONE_OF",
        "arity": 1,
        "param_formats": ["{values}"],
        "orm_template": "{col}__in",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "resource-instance-list",
        "label": "count is greater than",
        "operator": "COUNT_GREATER_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col_count}__gt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "resource-instance-list",
        "label": "count is less than",
        "operator": "COUNT_LESS_THAN",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col_count}__lt",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "resource-instance-list",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "resource-instance-list",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

STRING_FACETS = [
    {
        "datatype": "string",
        "label": "is like",
        "operator": "LIKE",
        "arity": 1,
        "param_formats": ["%{value}%"],
        "orm_template": "{col}__icontains",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "string",
        "label": "is not like",
        "operator": "NOT_LIKE",
        "arity": 1,
        "param_formats": ["%{value}%"],
        "orm_template": "{col}__icontains",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "string",
        "label": "starts with",
        "operator": "STARTS_WITH",
        "arity": 1,
        "param_formats": ["{value}%"],
        "orm_template": "{col}__istartswith",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "string",
        "label": "ends with",
        "operator": "ENDS_WITH",
        "arity": 1,
        "param_formats": ["%{value}"],
        "orm_template": "{col}__iendswith",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "string",
        "label": "equals",
        "operator": "EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__iexact",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "string",
        "label": "does not equal",
        "operator": "NOT_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__iexact",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "string",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "string",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

URL_FACETS = [
    {
        "datatype": "url",
        "label": "is like",
        "operator": "LIKE",
        "arity": 1,
        "param_formats": ["%{value}%"],
        "orm_template": "{col}__icontains",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "url",
        "label": "is not like",
        "operator": "NOT_LIKE",
        "arity": 1,
        "param_formats": ["%{value}%"],
        "orm_template": "{col}__icontains",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "url",
        "label": "starts with",
        "operator": "STARTS_WITH",
        "arity": 1,
        "param_formats": ["{value}%"],
        "orm_template": "{col}__istartswith",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "url",
        "label": "ends with",
        "operator": "ENDS_WITH",
        "arity": 1,
        "param_formats": ["%{value}"],
        "orm_template": "{col}__iendswith",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "url",
        "label": "equals",
        "operator": "EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__iexact",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "url",
        "label": "does not equal",
        "operator": "NOT_EQUALS",
        "arity": 1,
        "param_formats": ["{value}"],
        "orm_template": "{col}__iexact",
        "is_orm_template_negated": True,
    },
    {
        "datatype": "url",
        "label": "has no value",
        "operator": "HAS_NO_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": False,
    },
    {
        "datatype": "url",
        "label": "has any value",
        "operator": "HAS_ANY_VALUE",
        "arity": 0,
        "param_formats": [],
        "orm_template": "{col}__isnull",
        "is_orm_template_negated": True,
    },
]

ALL_FACETS = [
    *BOOLEAN_FACETS,
    *DATE_FACETS,
    *EDTF_FACETS,
    *FILE_LIST_FACETS,
    *GEOJSON_FEATURE_COLLECTION_FACETS,
    *NON_LOCALIZED_STRING_FACETS,
    *NUMBER_FACETS,
    *REFERENCE_FACETS,
    *RESOURCE_INSTANCE_FACETS,
    *RESOURCE_INSTANCE_LIST_FACETS,
    *STRING_FACETS,
    *URL_FACETS,
]


def seed_facets(apps, schema_editor):
    AdvancedSearchFacet = apps.get_model("arches_search", "AdvancedSearchFacet")
    DDataType = apps.get_model("models", "DDataType")

    for spec in ALL_FACETS:
        datatype = DDataType.objects.get(datatype=spec["datatype"])
        current_count = AdvancedSearchFacet.objects.filter(datatype=datatype).count()

        AdvancedSearchFacet.objects.create(
            arity=spec["arity"],
            datatype=datatype,
            label={"en": spec["label"]},
            operator=spec["operator"],
            param_formats=spec["param_formats"],
            sortorder=current_count,
            orm_template=spec["orm_template"],
            is_orm_template_negated=spec["is_orm_template_negated"],
        )


def unseed_facets(apps, schema_editor):
    AdvancedSearchFacet = apps.get_model("arches_search", "AdvancedSearchFacet")
    DDataType = apps.get_model("models", "DDataType")

    for spec in ALL_FACETS:
        datatype = DDataType.objects.get(datatype=spec["datatype"])

        AdvancedSearchFacet.objects.filter(
            datatype=datatype, operator=spec["operator"]
        ).delete()


class Migration(migrations.Migration):

    dependencies = [
        ("arches_search", "0002_indexed_tables"),
    ]

    operations = [
        migrations.CreateModel(
            name="AdvancedSearchFacet",
            fields=[
                ("id", models.AutoField(primary_key=True, serialize=False)),
                ("arity", models.PositiveSmallIntegerField(default=0)),
                (
                    "label",
                    arches.app.models.fields.i18n.I18n_TextField(
                        default="",
                        encoder=arches.app.utils.betterJSONSerializer.JSONSerializer,
                    ),
                ),
                ("operator", models.CharField(max_length=50)),
                ("param_formats", models.JSONField(blank=True, default=list)),
                ("sortorder", models.PositiveSmallIntegerField()),
                ("orm_template", models.CharField(blank=True, max_length=255)),
                ("is_orm_template_negated", models.BooleanField(default=False)),
                (
                    "datatype",
                    models.ForeignKey(
                        db_column="datatypeid",
                        help_text="The data type to which the advanced search facet applies.",
                        on_delete=django.db.models.deletion.CASCADE,
                        to="models.ddatatype",
                        verbose_name="Data Type",
                    ),
                ),
            ],
        ),
        migrations.AddConstraint(
            model_name="advancedsearchfacet",
            constraint=models.UniqueConstraint(
                fields=("datatype", "operator"), name="unique_operator_per_datatype"
            ),
        ),
        migrations.AddConstraint(
            model_name="advancedsearchfacet",
            constraint=models.UniqueConstraint(
                fields=("datatype", "sortorder"), name="unique_sortorder_per_datatype"
            ),
        ),
        migrations.RunPython(code=seed_facets, reverse_code=unseed_facets),
    ]
