from __future__ import absolute_import
from flask_sqlalchemy.query import Query as BaseQuery
from sqlalchemy import func

from dostadmin import db, app_logger
from utils.helpers.helpers import replace_chars
from dostadmin.mixins import TimestampMixin


class PartnerQuery(BaseQuery):
    def get_id_with_name(self, ip_name="others"):
        partner_rec = self.filter(
            Partner.name == replace_chars(ip_name.lower())
        ).first()
        if partner_rec:
            return partner_rec.id
        return -1

    def get_partners_log(self, current_page):
        return Partner.query.order_by(Partner.id.desc()).paginate(
            page=current_page, per_page=30, error_out=False
        )

    def get_by_name(self, name):
        return self.filter(func.lower(Partner.name) == name.lower().strip()).first()

    def get_by_id(self, partner_id):
        return self.filter(Partner.id == partner_id).first()

    def get_partner_by_channel(self, channel_id):
        return self.filter(Partner.channel_id == channel_id).all()

    def get_partner_by_email(self, email):
        return self.filter(Partner.email == email).first()

    def get_partner_by_state_and_district(self, state, district):
        return self.filter(
            func.lower(Partner.state) == state.lower(),
            func.lower(Partner.district) == district.lower(),
        ).all()

    def get_partner_by_state(self, state):
        return self.filter(func.lower(Partner.state) == state.lower()).all()

    def get_partner_by_district(self, district):
        return self.filter(func.lower(Partner.district) == district.lower()).all()

    def get_partner_by_state_district_and_block(self, state, district, block):
        return self.filter(
            func.lower(Partner.state) == state.lower(),
            func.lower(Partner.district) == district.lower(),
            func.lower(Partner.block) == block.lower(),
        ).first()

    def get_partner_by_block(self, block):
        return self.filter(func.lower(Partner.block) == block.lower()).first()


class Partner(TimestampMixin, db.Model):
    __tablename__ = "partner"
    query_class = PartnerQuery

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), unique=True, nullable=False)
    area = db.Column(db.String(20))
    city = db.Column(db.String(20))
    state = db.Column(db.String(50))
    district = db.Column(db.String(50))
    block = db.Column(db.String(50))
    channel_id = db.Column(db.Integer, db.ForeignKey("channel.id"))
    email = db.Column(db.String(100))

    users = db.relationship(
        "User", backref="partner", primaryjoin="Partner.id == User.partner_id"
    )
    teachers = db.relationship(
        "Teacher", backref="school", primaryjoin="Partner.id == Teacher.school_id"
    )
    school_leaders = db.relationship(
        "SchoolLeader",
        backref="school",
        primaryjoin="Partner.id == SchoolLeader.school_id",
    )

    def __repr__(self):
        return (
            "Partner "
            + self.name
            + " "
            + self.area
            + ","
            + self.city
            + " "
            + str(self.id)
        )

    @classmethod
    def delete_partner(cls, partner_id):
        app_logger.info("Deleting partner with id: %d", partner_id)
        partner_rec = Partner.query.get_by_id(partner_id)
        db.session.delete(partner_rec)
        db.session.commit()
