import json
import logging
from odoo import http
from odoo.http import request
from odoo.addons.encoach_api.controllers.base import (
    jwt_required, _json_response, _error_response, _get_json_body, _paginate,
    validate_token,
)

_logger = logging.getLogger(__name__)


class EncoachBrandingController(http.Controller):

    # ------------------------------------------------------------------
    # GET /api/entity/<int:entity_id>/level-mapping
    # ------------------------------------------------------------------
    @http.route('/api/entity/<int:entity_id>/level-mapping', type='http',
                auth='none', methods=['GET'], csrf=False)
    @jwt_required
    def get_level_mapping(self, entity_id, **kw):
        try:
            Entity = request.env['encoach.entity'].sudo()
            entity = Entity.browse(entity_id)
            if not entity.exists():
                return _error_response('Entity not found', 404)

            Mapping = request.env['encoach.entity.level.mapping'].sudo()
            mappings = Mapping.search(
                [('entity_id', '=', entity_id)],
                order='min_score asc',
            )

            items = []
            for m in mappings:
                items.append({
                    'id': m.id,
                    'entity_id': m.entity_id.id,
                    'min_score': m.min_score,
                    'max_score': m.max_score,
                    'internal_level_name': m.internal_level_name,
                    'cefr_equivalent': m.cefr_equivalent or '',
                })

            return _json_response({'mappings': items})

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

    # ------------------------------------------------------------------
    # PUT /api/entity/<int:entity_id>/level-mapping
    # ------------------------------------------------------------------
    @http.route('/api/entity/<int:entity_id>/level-mapping', type='http',
                auth='none', methods=['PUT'], csrf=False)
    @jwt_required
    def update_level_mapping(self, entity_id, **kw):
        try:
            body = _get_json_body()
            mappings_data = body.get('mappings', [])
            if not mappings_data:
                return _error_response('mappings list is required', 400)

            Entity = request.env['encoach.entity'].sudo()
            entity = Entity.browse(entity_id)
            if not entity.exists():
                return _error_response('Entity not found', 404)

            Mapping = request.env['encoach.entity.level.mapping'].sudo()
            Mapping.search([('entity_id', '=', entity_id)]).unlink()

            new_mappings = []
            for md in mappings_data:
                if not md.get('internal_level_name'):
                    return _error_response('internal_level_name is required for each mapping', 400)

                rec = Mapping.create({
                    'entity_id': entity_id,
                    'min_score': float(md.get('min_score', 0)),
                    'max_score': float(md.get('max_score', 0)),
                    'internal_level_name': md['internal_level_name'],
                    'cefr_equivalent': md.get('cefr_equivalent') or False,
                })
                new_mappings.append({
                    'id': rec.id,
                    'entity_id': rec.entity_id.id,
                    'min_score': rec.min_score,
                    'max_score': rec.max_score,
                    'internal_level_name': rec.internal_level_name,
                    'cefr_equivalent': rec.cefr_equivalent or '',
                })

            return _json_response({'mappings': new_mappings})

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

    # ------------------------------------------------------------------
    # GET /api/entity/<int:entity_id>/branding
    # ------------------------------------------------------------------
    @http.route('/api/entity/<int:entity_id>/branding', type='http',
                auth='none', methods=['GET'], csrf=False)
    @jwt_required
    def get_entity_branding(self, entity_id, **kw):
        try:
            Branding = request.env['encoach.branding'].sudo()
            branding = Branding.search([('entity_id', '=', entity_id)], limit=1)
            if not branding:
                return _error_response('Branding not found for this entity', 404)

            return _json_response(branding.to_api_dict())

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

    # ------------------------------------------------------------------
    # PUT /api/entity/<int:entity_id>/branding
    # ------------------------------------------------------------------
    @http.route('/api/entity/<int:entity_id>/branding', type='http',
                auth='none', methods=['PUT'], csrf=False)
    @jwt_required
    def update_entity_branding(self, entity_id, **kw):
        try:
            body = _get_json_body()

            Entity = request.env['encoach.entity'].sudo()
            entity = Entity.browse(entity_id)
            if not entity.exists():
                return _error_response('Entity not found', 404)

            Branding = request.env['encoach.branding'].sudo()
            branding = Branding.search([('entity_id', '=', entity_id)], limit=1)

            allowed = [
                'primary_color', 'secondary_color', 'background_color',
                'app_name', 'login_title', 'login_description',
                'white_label_domain', 'custom_css',
            ]
            vals = {k: body[k] for k in allowed if k in body}

            if not branding:
                vals['entity_id'] = entity_id
                branding = Branding.create(vals)
            else:
                branding.write(vals)

            return _json_response(branding.to_api_dict())

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

    # ------------------------------------------------------------------
    # GET /api/entity/branding  (combined public + authenticated)
    # GET /api/entity/branding/public
    #
    # If ?domain=<subdomain> is present  → public lookup, no auth needed.
    # Otherwise                          → JWT required, return user entity branding.
    # ------------------------------------------------------------------
    @http.route(
        ['/api/entity/branding', '/api/entity/branding/public'],
        type='http', auth='none', methods=['GET'], csrf=False,
    )
    def get_branding(self, **kw):
        try:
            domain_param = kw.get('domain')

            if domain_param:
                Branding = request.env(su=True)['encoach.branding']
                branding = Branding.search(
                    [('white_label_domain', '=', domain_param)], limit=1,
                )
                if not branding:
                    return _error_response('Branding not found for this domain', 404)

                return _json_response({
                    'app_name': branding.app_name or 'EnCoach',
                    'primary_color': branding.primary_color or '#4F46E5',
                    'secondary_color': branding.secondary_color or '#7C3AED',
                    'background_color': branding.background_color or '#FFFFFF',
                    'has_logo': bool(branding.logo),
                    'logo_url': branding.logo_url or '',
                    'login_title': branding.login_title or '',
                    'login_description': branding.login_description or '',
                    'custom_css': branding.custom_css or '',
                })

            user = validate_token()
            if not user:
                return _error_response('Missing or invalid Authorization header', 401)
            entity = user.entity_ids[:1]
            if not entity:
                return _error_response('User has no associated entity', 404)

            Branding = request.env['encoach.branding'].sudo()
            branding = Branding.search([('entity_id', '=', entity.id)], limit=1)
            if not branding:
                return _json_response({
                    'entity_id': entity.id,
                    'entity_name': entity.name,
                    'app_name': 'EnCoach',
                    'primary_color': entity.primary_color or '#4F46E5',
                    'secondary_color': entity.secondary_color or '#7C3AED',
                    'background_color': entity.background_color or '#FFFFFF',
                    'has_logo': bool(entity.logo),
                    'logo_url': entity.logo_url or '',
                    'login_title': entity.login_title or '',
                    'login_description': entity.login_description or '',
                })

            return _json_response(branding.to_api_dict())

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