from typing import Any

from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession


class AuthRepository:
    def __init__(self, session: AsyncSession) -> None:
        self.session = session

    async def find_pengguna(self, username: str) -> dict[str, Any] | None:
        result = await self.session.execute(
            text(
                """
                SELECT kodepengguna, namapengguna, password, hakakses, kodedivisi, DLT
                FROM mspengguna
                WHERE (kodepengguna = :u OR namapengguna = :u)
                  AND (DLT = '0' OR DLT IS NULL OR DLT = '')
                LIMIT 1
                """
            ),
            {"u": username},
        )
        row = result.mappings().one_or_none()
        return dict(row) if row else None

    async def find_sales(self, username: str) -> dict[str, Any] | None:
        result = await self.session.execute(
            text(
                """
                SELECT kodesales, namasales, password, status, aktif, DLT
                FROM mssales
                WHERE (kodesales = :u OR namasales = :u)
                  AND (DLT = '0' OR DLT IS NULL OR DLT = '')
                  AND (aktif = 'AKTIF' OR aktif IS NULL OR status = 'AKTIF')
                LIMIT 1
                """
            ),
            {"u": username},
        )
        row = result.mappings().one_or_none()
        return dict(row) if row else None

    async def record_login(
        self,
        kodepengguna: str,
        namahost: str | None,
        jenisaplikasi: str | None,
        version: str | None,
        ip_address: str | None,
    ) -> int | None:
        app_type = (jenisaplikasi or "ANDROID").upper()[:20]
        result = await self.session.execute(
            text(
                """
                INSERT INTO mslogin (
                    kodepengguna, logintime, namahost, jenisaplikasi, version, IPADRRES, DLT
                ) VALUES (
                    :kodepengguna, NOW(), :namahost, :jenisaplikasi, :version, :ip_address, '0'
                )
                """
            ),
            {
                "kodepengguna": kodepengguna,
                "namahost": namahost[:100] if namahost else None,
                "jenisaplikasi": app_type,
                "version": version[:50] if version else None,
                "ip_address": ip_address[:100] if ip_address else None,
            },
        )
        await self.session.commit()
        return result.lastrowid

    async def record_logout(self, login_id: int, kodepengguna: str) -> bool:
        result = await self.session.execute(
            text(
                """
                UPDATE mslogin
                SET logouttime = NOW()
                WHERE ID = :login_id
                  AND kodepengguna = :kodepengguna
                  AND (DLT = '0' OR DLT IS NULL)
                """
            ),
            {"login_id": login_id, "kodepengguna": kodepengguna},
        )
        await self.session.commit()
        return (result.rowcount or 0) > 0
