from __future__ import absolute_import
from flask_sqlalchemy.query import Query as BaseQuery
from sqlalchemy import func, and_, or_
from dostadmin import db
from utils.helpers.helpers import replace_chars
from dostadmin.mixins import TimestampMixin


class ProgramQuery(BaseQuery):
    def find_program_id_with_name(self, program_name):
        p_rec = self.filter(
            func.lower(Program.name) == replace_chars(program_name)
        ).first()
        if p_rec:
            return p_rec.id
        return -1

    def find_program_obj_with_name(self, program_name):
        p_rec = self.filter(
            func.lower(Program.name) == replace_chars(program_name)
        ).first()
        return p_rec

    def get_program_by_type(self, program_type):
        return self.filter(Program.type == program_type).all()

    def get_program_by_status(self, status):
        return self.filter(Program.status == status).all()

    def get_program_by_status_and_type(self, status, program_type):
        return self.filter(and_(Program.status == status, Program.type == program_type))

    def get_uk_active_programs(self, status):
        return self.filter(
            or_(
                Program.name == Program.Name.UK_USN_B_3,
                Program.name == Program.Name.UK_USN_T_6,
            ),
            Program.status == status,
        )

    def get_programs_log(self):
        return self.all()

    def get_paginated_programs_log(self, page=1, per_page=30):
        return self.paginate(page=page, per_page=per_page, error_out=False)

    def get_program_details(self, program_id):
        return self.filter(Program.id == program_id).first()


class Program(TimestampMixin, db.Model):
    __tablename__ = "program"
    query_class = ProgramQuery

    class Type:
        REGULAR = "regular"
        STREAK = "streak"
        STREAK_OPTIN = "streak-optin"
        INTRO_CALL = "intro-call"
        BLAST = "blast"
        TRIGGER = "trigger"
        FOUNDATION = "foundation"
        WHATSAPP = "wa"

    class Name:
        R2L_COVID_RESHUFFLED = "R2L_COVID_reshuffled"
        R2L_COVID_v2 = "R2L_COVID_v2"
        UK_USN_B_3 = "UK-USN_B-3"
        UK_USN_T_6 = "UK-USN_T-6"
        VS_ASSAM_B_3 = "VS_ASSAM_B-3"
        VS_ASSAM_T_6 = "VS_ASSAM_T-6"
        UK_USN_B_3_HINDI = "यूके यूएसएन बी 3"
        UK_USN_T_6_HINDI = "यूके यूएसएन टी 6"

        HINDI_NAME = (
            (UK_USN_B_3, UK_USN_B_3_HINDI),
            (UK_USN_T_6, UK_USN_T_6_HINDI),
        )

    class Status:
        ACTIVE = "active"
        INACTIVE = "inactive"

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), unique=True, nullable=False)
    version = db.Column(db.Integer)
    start_date = db.Column(db.Date)
    end_date = db.Column(db.Date)
    description = db.Column(db.String(400))
    hindi_name = db.Column(db.String(100))
    status = db.Column(db.String(30))
    type = db.Column(db.String(30))
    experiences = db.relationship(
        "Experience",
        backref="program",
        primaryjoin="Program.id == Experience.program_id",
    )
    programseq = db.relationship(
        "Programseq",
        backref="Program",
        primaryjoin="Program.id == Programseq.program_id",
    )
    behaviors = db.relationship(
        "Behavior", backref="program", primaryjoin="Behavior.program_id == Program.id"
    )

    def __repr__(self):
        return (
            "\n Program: id_ "
            + str(self.id)
            + ", name: "
            + str(self.name)
            + ", version: "
            + str(self.version)
        )
