import sqlalchemy as sa
from geoalchemy2 import Geometry
from sqlalchemy import func

from maps_adv.points.server.lib.enums import PointType

__all__ = ["collections", "points", "shows_forecasts", "metadata"]

_constaints_naming_convention = {
    "ix": "ix_%(column_0_label)s",
    "uq": "uq_%(table_name)s_%(column_0_name)s",
    "ck": "ck_%(table_name)s_%(constraint_name)s",
    "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
    "pk": "pk_%(table_name)s",
}

metadata = sa.MetaData(naming_convention=_constaints_naming_convention)


collections = sa.Table(
    "collections",
    metadata,
    sa.Column("id", sa.Integer, primary_key=True),
    sa.Column("type", sa.Enum(PointType), nullable=False),
    sa.Column("version", sa.Integer, nullable=False),
    sa.UniqueConstraint("type", "version"),
)

points = sa.Table(
    "points",
    metadata,
    sa.Column("id", sa.Integer, primary_key=True),
    sa.Column(
        "geometry",
        Geometry(geometry_type="POINT", srid=4326, spatial_index=False),
        nullable=False,
    ),
    sa.Column(
        "collection_id", sa.Integer, sa.ForeignKey("collections.id"), nullable=False
    ),
    sa.UniqueConstraint("geometry", "collection_id"),
    sa.Index("points_geometry_gist_index", "geometry", postgresql_using="gist"),
)

shows_forecasts = sa.Table(
    "shows_forecasts",
    metadata,
    sa.Column("geohash", sa.String(length=6), nullable=False, primary_key=True),
    sa.Column("pin_shows", sa.Integer, nullable=False),
    sa.Column("billboard_shows", sa.Integer, nullable=False),
    sa.Column("zsb_shows", sa.Integer, nullable=False),
    sa.Column("overview_shows", sa.Integer, nullable=False, server_default="0"),
    sa.CheckConstraint("length(geohash) = 6", name="geohash_length"),
    sa.Index(
        "shows_forecasts_geohash_as_shifted_point",
        func.ST_ShiftLongitude(
            func.ST_SetSRID(func.ST_PointFromGeoHash("geohash"), 4326)
        ),
        postgresql_using="gist",
    ),
    sa.Index("shows_forecasts_geohash_hash", "geohash", postgresql_using="hash"),
)


spatial_ref_sys = sa.Table(
    "spatial_ref_sys",
    metadata,
    sa.Column("srid", sa.Integer, primary_key=True),
    sa.Column("auth_name", sa.String(length=256)),
    sa.Column("auth_srid", sa.Integer),
    sa.Column("srtext", sa.String(length=2048)),
    sa.Column("proj4text", sa.String(length=2048)),
)
