from sqlalchemy import or_
from sqlalchemy.orm import Session

from app.models.customer import Customer


class CustomerRepository:
    def __init__(self, db: Session):
        self.db = db

    def get_by_id(self, customer_id: int, agency_id: int) -> Customer | None:
        return (
            self.db.query(Customer)
            .filter(Customer.id == customer_id, Customer.agency_id == agency_id, Customer.deleted_at.is_(None))
            .first()
        )

    def list_paginated(self, agency_id: int, page: int, page_size: int, search: str | None = None) -> tuple[list[Customer], int]:
        query = self.db.query(Customer).filter(Customer.agency_id == agency_id, Customer.deleted_at.is_(None))
        if search:
            pattern = f"%{search}%"
            query = query.filter(or_(Customer.name.ilike(pattern), Customer.mobile.ilike(pattern)))
        total = query.count()
        items = query.order_by(Customer.name.asc()).offset((page - 1) * page_size).limit(page_size).all()
        return items, total

    def get_by_mobile(self, agency_id: int, mobile: str) -> Customer | None:
        return (
            self.db.query(Customer)
            .filter(Customer.agency_id == agency_id, Customer.mobile == mobile, Customer.deleted_at.is_(None))
            .first()
        )

    def list_by_agency(self, agency_id: int) -> list[Customer]:
        return (
            self.db.query(Customer)
            .filter(Customer.agency_id == agency_id, Customer.deleted_at.is_(None))
            .all()
        )

    def create(self, agency_id: int, data: dict) -> Customer:
        customer = Customer(agency_id=agency_id, **data)
        self.db.add(customer)
        self.db.flush()
        return customer

    def update(self, customer: Customer, data: dict) -> Customer:
        for key, value in data.items():
            setattr(customer, key, value)
        self.db.flush()
        return customer

    def soft_delete(self, customer: Customer) -> None:
        from datetime import datetime, timezone

        customer.deleted_at = datetime.now(timezone.utc)
        self.db.flush()
