from uuid import UUID
from typing import Optional
from app.modules.partners.domain.entities import Partner

class PartnerRepository:
    """
    Adapter nối Domain Entity Partner xuống bảng PostgreSQL.
    Luôn cô lập trong Schema 'partners'.
    """
    def __init__(self, conn):
        self._conn = conn

    def ensure_schema(self):
        with self._conn.cursor() as cur:
            cur.execute("""
                CREATE SCHEMA IF NOT EXISTS partners;
                CREATE TABLE IF NOT EXISTS partners.partners (
                    id UUID PRIMARY KEY,
                    name TEXT NOT NULL,
                    tax_code TEXT,
                    type TEXT NOT NULL,
                    address TEXT,
                    created_at TIMESTAMP WITH TIME ZONE
                );
                -- Unique index cho mã số thuế nếu có
                CREATE UNIQUE INDEX IF NOT EXISTS idx_partners_tax_code 
                ON partners.partners(tax_code) 
                WHERE tax_code IS NOT NULL;
            """)

    def save(self, partner: Partner) -> None:
        self.ensure_schema()
        with self._conn.cursor() as cur:
            cur.execute("""
                INSERT INTO partners.partners 
                (id, name, tax_code, type, address, created_at)
                VALUES (%s, %s, %s, %s, %s, %s)
                ON CONFLICT (id) DO UPDATE SET
                    name = EXCLUDED.name,
                    tax_code = EXCLUDED.tax_code,
                    type = EXCLUDED.type,
                    address = EXCLUDED.address;
            """, (
                str(partner.id),
                partner.name,
                partner.tax_code,
                partner.type,
                partner.address,
                partner.created_at
            ))

    def get_by_id(self, partner_id: UUID) -> Optional[Partner]:
        with self._conn.cursor() as cur:
            cur.execute("SELECT * FROM partners.partners WHERE id = %s", (str(partner_id),))
            row = cur.fetchone()
            if row:
                return Partner(**row)
        return None
