from fastapi import HTTPException, Depends, Header
from psycopg2.extras import DictCursor
from utils import (
    get_db_connection, 
)
from pytz import timezone
from datetime import datetime
import jwt
from models.customer import (
    Customer,
    Response,
)
from services.company import CompanyService
from services.encryption import EncryptionService


SAO_PAULO_TZ = timezone('America/Sao_Paulo')

class CustomerController:
    def store(self, cookie: str):
        try:
            fgtsd_token_str = next((s.split('=')[1] for s in cookie.split('; ') if s.startswith('fgtsd_token=')), None)

            if not fgtsd_token_str:
                raise ValueError("O 'fgtsd_token' não foi encontrado na string de cookie.")
            
            decoded_token = jwt.decode(fgtsd_token_str, options={"verify_signature": False})

            company_cnpj = decoded_token.get("cnpj")
            if not company_cnpj:
                raise ValueError("CNPJ da empresa não encontrado no token.")
            
            company_id = CompanyService.get_company_id_by_cnpj(company_cnpj)
                    
            cnpj = decoded_token.get("fgtsdigital.gov.br/ni_perfil")
            name = decoded_token.get("fgtsdigital.gov.br/nome_perfil")
            exp_timestamp = decoded_token.get("exp")

            if not company_id:
                raise ValueError("Empresa não cadastrada no sistema.")

            if not all([cnpj, name, exp_timestamp]):
                raise ValueError("JWT inválido. Faltam campos essenciais.")

            if not isinstance(cnpj, str):
                raise ValueError("CNPJ deve ser uma string válida.")

            if not isinstance(exp_timestamp, (int, float)):
                raise ValueError("Timestamp de expiração deve ser um número válido.")
            
            # return {company_id} 

            exp_datetime = datetime.fromtimestamp(exp_timestamp, tz=SAO_PAULO_TZ)
            encrypted_cookie = EncryptionService.encrypt_data(cookie)
            
            conn = get_db_connection()
            try:
                with conn.cursor() as cur:
                        query = """
                            INSERT INTO customers 
                            (company_id, cnpj, name, cookie, expires_on, status, updated_at)
                            VALUES (%s, %s, %s, %s, %s, 'active', %s) 
                            ON CONFLICT (company_id, cnpj) DO UPDATE SET
                                name = EXCLUDED.name,
                                cookie = EXCLUDED.cookie,
                                expires_on = EXCLUDED.expires_on,
                                status = 'active',
                                updated_at = NOW(),
                                details = NULL;
                        """
                        cur.execute(query, (company_id, cnpj, name, encrypted_cookie, exp_datetime, datetime.now(SAO_PAULO_TZ)))
                        conn.commit()
                return Response(
                    status="success",
                    message="Cliente registrada com sucesso.",
                    data={
                        "cnpj": cnpj,
                        "name": name,
                        "action": "created",
                        "expires_on": exp_datetime
                    }
                )
            finally:
                conn.close()
        except (ValueError, jwt.PyJWTError) as e:
            raise HTTPException(status_code=400, detail=str(e))
        except Exception as e:
            print(f"Erro inesperado no registro: {e}")
            raise HTTPException(status_code=500, detail="Ocorreu um erro interno no servidor.")

    def show(self, cnpj: str):
        conn = get_db_connection()
        try:
            with conn.cursor(cursor_factory=DictCursor) as cur:
                cur.execute("SELECT * FROM customers WHERE cnpj = %s;", (cnpj,))
                customer = cur.fetchone()
            if not customer:
                return None
            
            customer = dict(customer)
            customer['cookie'] = EncryptionService.decrypt_data(customer['cookie'])

            return Customer(**customer)
        finally:
            conn.close()

    def delete(self, cnpj: str):
        conn = get_db_connection()
        try:
            with conn.cursor(cursor_factory=DictCursor) as cur:
                cur.execute("DELETE FROM customers WHERE cnpj = %s RETURNING *;", (cnpj,))
                customer = cur.fetchone()
                
                if not customer:
                    raise HTTPException(status_code=404, detail="Cliente não encontrado para remover.")
                
                conn.commit()
                
                return Response(
                    status="success",
                    message="Cliente removido com sucesso.",
                    data={
                        "cnpj": customer['cnpj'],
                        "name": customer['name'],
                        "action": "deleted",
                        "expires_on": customer['expires_on']
                    }
                )
        finally:
            conn.close()