import logging
import time

import jwt as pyjwt

from odoo import http, fields
from odoo.http import request
from odoo.exceptions import AccessDenied

from .base import (
    _json_response, _error_response, _get_json_body, _get_jwt_secret, validate_token,
)

_logger = logging.getLogger(__name__)


class EncoachAuthController(http.Controller):

    # ------------------------------------------------------------------
    # POST /api/login
    # ------------------------------------------------------------------
    @http.route('/api/login', type='http', auth='public',
                methods=['POST'], csrf=False)
    def login(self, **kw):
        try:
            body = _get_json_body()
            login = (body.get('login') or body.get('email') or '').strip().lower()
            password = body.get('password', '')

            if not login or not password:
                return _error_response('login and password are required', 400)

            # Odoo 19: session.authenticate(env, credential_dict)
            credential = {
                'type': 'password',
                'login': login,
                'password': password,
            }
            try:
                request.session.authenticate(request.env, credential)
                uid = request.session.uid
                if not uid:
                    return _error_response('Invalid email or password', 401)
            except AccessDenied:
                return _error_response('Invalid email or password', 401)
            except Exception as auth_err:
                _logger.warning('Auth error for %s: %s', login, auth_err)
                return _error_response('Invalid email or password', 401)

            user = request.env['res.users'].sudo().browse(uid)

            # Generate JWT token
            secret = _get_jwt_secret()
            if not secret:
                return _error_response('JWT not configured on server', 500)

            token = pyjwt.encode(
                {'user_id': user.id, 'exp': int(time.time()) + 86400},
                secret, algorithm='HS256',
            )

            # Get permissions
            permissions = []
            if hasattr(user, 'get_all_permissions'):
                permissions = user.get_all_permissions().mapped('code')

            # Update last login
            user.write({'last_login': fields.Datetime.now()})

            return _json_response({
                'token': token,
                'user': self._user_to_dict(user),
                'permissions': permissions,
            })

        except Exception as e:
            _logger.exception('login failed')
            return _error_response(str(e), 500)

    # ------------------------------------------------------------------
    # GET /api/user  (returns current authenticated user)
    # ------------------------------------------------------------------
    @http.route('/api/user', type='http', auth='public',
                methods=['GET'], csrf=False)
    def get_current_user(self, **kw):
        try:
            user = validate_token()
            if not user:
                return _error_response('Authentication required', 401)

            permissions = []
            if hasattr(user, 'get_all_permissions'):
                permissions = user.get_all_permissions().mapped('code')

            return _json_response({
                'user': self._user_to_dict(user),
                'permissions': permissions,
            })

        except Exception as e:
            _logger.exception('get_current_user failed')
            return _error_response(str(e), 500)

    # ------------------------------------------------------------------
    # POST /api/logout
    # ------------------------------------------------------------------
    @http.route('/api/logout', type='http', auth='public',
                methods=['POST'], csrf=False)
    def logout(self, **kw):
        # JWT is stateless — client clears token. Server just returns OK.
        return _json_response({'ok': True})

    # ------------------------------------------------------------------
    # helpers
    # ------------------------------------------------------------------
    def _user_to_dict(self, user):
        """Convert res.users to the dict shape the React frontend expects."""
        entities = []
        if hasattr(user, 'entity_ids'):
            entities = [
                {'id': e.id, 'name': e.name, 'role': ''}
                for e in user.entity_ids
            ]

        classrooms = []

        return {
            'id': user.id,
            'name': user.name or '',
            'email': user.email or '',
            'login': user.login or '',
            'user_type': getattr(user, '_api_user_type', lambda: user.user_type or 'student')()
                         if callable(getattr(user, '_api_user_type', None))
                         else (user.user_type or 'student'),
            'avatar': bool(getattr(user, 'encoach_avatar', False)),
            'phone': user.phone or '',
            'country': '',
            'timezone': '',
            'bio': '',
            'gender': getattr(user, 'gender', '') or '',
            'student_id': '',
            'is_verified': getattr(user, 'is_verified', False),
            'entities': entities,
            'classrooms': classrooms,
            'expiry_date': '',
        }
