from typing import Dict
import os

class EventQueryBuilder:
    def __init__(self, property_id:str, config: Dict):
        self.config = config
        self.select_clause = "SELECT DISTINCT user_pseudo_id"
        self.base_table = f"FROM `{os.environ.get('GCP_PROJECT')}.client_{property_id}.event` AS main"
        self.user_table = f"FROM `{os.environ.get('GCP_PROJECT')}.client_{property_id}.user` AS user"
        self.joins = []
        self.where_clauses = []
    
    def resolve_operator(self, field: str, operator: str, value) -> str:
        if isinstance(value, list):
            if operator == "=" or operator == "in":
                values = ", ".join(f"'{v}'" for v in value)
                return f"{field} IN ({values})"
            elif operator == "!=" or operator == "not in":
                values = ", ".join(f"'{v}'" for v in value)
                return f"{field} NOT IN ({values})"
            elif operator == "contains":
                return " OR ".join(f"{field} LIKE '%{v}%'" for v in value)
            elif operator == "startswith":
                return " OR ".join(f"{field} LIKE '{v}%'" for v in value)
            elif operator == "endswith":
                return " OR ".join(f"{field} LIKE '%{v}'" for v in value)
            else:
                raise ValueError(f"Unsupported operator with list: {operator}")
        else:
            # single value
            if operator == "=":
                return f"{field} = '{value}'"
            elif operator == "!=":
                return f"{field} != '{value}'"
            elif operator == "contains":
                return f"{field} LIKE '%{value}%'"
            elif operator == "startswith":
                return f"{field} LIKE '{value}%'"
            elif operator == "endswith":
                return f"{field} LIKE '%{value}'"
            elif operator == "in":
                return f"{field} IN ('{value}')"
            else:
                raise ValueError(f"Unsupported operator: {operator}")


    def build_event_name_filter(self):
        event_name = self.config.get("event")
        if event_name:
            self.where_clauses.append(f"eventName = '{event_name}'")

    def build_page_filter(self):
        if "page_id" in self.config:
            self.where_clauses.append(f"pageId = '{self.config['page_id']}'")
        if "page_source" in self.config:
            self.where_clauses.append(f"source = '{self.config['page_source']}'")

    def build_date_range(self):
        date_range = self.config.get("date_range", {})
        operator = date_range.get("operator")
        
        if operator == "last_n_days":
            days = int(date_range.get("days", 30))
            self.where_clauses.append(
                f"eventTimeStamp BETWEEN DATETIME_SUB(CURRENT_DATETIME(), INTERVAL {days} DAY) AND CURRENT_DATETIME()"
            )

        elif operator == "specific":
            start = date_range.get("start")
            end = date_range.get("end")
            if start and end:
                self.where_clauses.append(
                    f"eventTimeStamp BETWEEN DATETIME('{start}') AND DATETIME('{end}')"
                )

    def build_event_property_filter(self):
        prop = self.config.get("properties", {})
        field = prop.get("field")
        op = prop.get("operator")
        value = prop.get("value")
        if field and op and value is not None:
            self.select_clause += f", ep.value AS `{field}`"
            self.joins.append("LEFT JOIN UNNEST(eventProperty) AS ep")
            condition = f"ep.key = '{field}' AND " + self.resolve_operator("ep.value", op, value)
            self.where_clauses.append(condition)

    def build_query(self) -> str:
        self.build_event_name_filter()
        self.build_page_filter()
        self.build_date_range()
        self.build_event_property_filter()

        join_clause = "\n".join(self.joins)
        where_clause = f"\nWHERE {' AND '.join(self.where_clauses)}" if self.where_clauses else ""

        return f"""{self.select_clause}
{self.base_table}
{join_clause}
{where_clause}"""

class QueryGenerator:
    def __init__(self, property_id:str, config: Dict):
        self.property_id = property_id
        self.config = config

    def generate(self) -> str:
        builder = EventQueryBuilder(self.property_id, self.config)
        return builder.build_query()