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.company import (
    Company,
    Response,
)
from services.encryption import EncryptionService

SAO_PAULO_TZ = timezone('America/Sao_Paulo')

class CompanyController:
    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})
            cnpj = decoded_token.get("cnpj")
            name = decoded_token.get("cnpj_nome")
            exp_timestamp = decoded_token.get("exp")

            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.")

            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 companies (cnpj, name, cookie, expires_on, status, updated_at)
                        VALUES (%s, %s, %s, %s, 'active', %s) ON CONFLICT (cnpj) DO UPDATE SET
                            name = EXCLUDED.name, cookie = EXCLUDED.cookie,
                            expires_on = EXCLUDED.expires_on, status = 'active', updated_at = EXCLUDED.updated_at, details = NULL;
                    """
                    cur.execute(query, (cnpj, name, encrypted_cookie, exp_datetime, datetime.now(SAO_PAULO_TZ)))
                    conn.commit()
                return Response(
                    status="success",
                    message="Empresa 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 companies WHERE cnpj = %s;", (cnpj,))
                company = cur.fetchone()
            if not company:
                return None
            
            company = dict(company)
            company['cookie'] = EncryptionService.decrypt_data(company['cookie'])

            return Company(**company)
        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 companies WHERE cnpj = %s RETURNING *;", (cnpj,))
                company = cur.fetchone()
                
                if not company:
                    raise HTTPException(status_code=404, detail="Empresa não encontrada para remover.")
                
                conn.commit()
                
                return Response(
                    status="success",
                    message="Empresa removida com sucesso.",
                    data={
                        "cnpj": company['cnpj'],
                        "name": company['name'],
                        "action": "deleted",
                        "expires_on": company['expires_on']
                    }
                )
        finally:
            conn.close()