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,
)

_logger = logging.getLogger(__name__)


def _ser_leave(r):
    return {
        'id': r.id,
        'request_number': r.request_number or '',
        'student_id': r.student_id.id if r.student_id else 0,
        'student_name': r.student_id.partner_id.name if r.student_id and r.student_id.partner_id else '',
        'leave_type': r.leave_type_id.name if r.leave_type_id else '',
        'leave_type_id': r.leave_type_id.id if r.leave_type_id else 0,
        'start_date': str(r.start_date) if r.start_date else '',
        'end_date': str(r.end_date) if r.end_date else '',
        'duration': r.duration or 0,
        'description': r.description or '',
        'state': r.state or 'draft',
        'approve_date': str(r.approve_date) if r.approve_date else None,
    }


class StudentLeaveController(http.Controller):

    @http.route('/api/student-leaves', type='http', auth='public', methods=['GET'], csrf=False)
    @jwt_required
    def list_leaves(self, **kw):
        try:
            M = request.env['encoach.student.leave'].sudo()
            offset, limit, page = _paginate(kw)
            total = M.search_count([])
            recs = M.search([], offset=offset, limit=limit, order='create_date desc')
            items = [_ser_leave(r) for r in recs]
            return _json_response({'items': items, 'data': items, 'total': total, 'page': page, 'size': limit})
        except Exception as e:
            return _error_response(str(e), 500)

    @http.route('/api/student-leaves', type='http', auth='public', methods=['POST'], csrf=False)
    @jwt_required
    def create_leave(self, **kw):
        try:
            body = _get_json_body()
            vals = {
                'start_date': body.get('start_date'),
                'end_date': body.get('end_date'),
            }
            if body.get('student_id'):
                vals['student_id'] = int(body['student_id'])
            if body.get('leave_type'):
                vals['leave_type_id'] = int(body['leave_type'])
            if body.get('leave_type_id'):
                vals['leave_type_id'] = int(body['leave_type_id'])
            if body.get('description'):
                vals['description'] = body['description']
            rec = request.env['encoach.student.leave'].sudo().create(vals)
            return _json_response(_ser_leave(rec))
        except Exception as e:
            return _error_response(str(e), 500)

    @http.route('/api/student-leaves/<int:lid>', type='http', auth='public', methods=['PATCH', 'PUT'], csrf=False)
    @jwt_required
    def update_leave(self, lid, **kw):
        try:
            rec = request.env['encoach.student.leave'].sudo().browse(lid)
            if not rec.exists():
                return _error_response('Not found', 404)
            body = _get_json_body()
            vals = {}
            for k in ('start_date', 'end_date', 'description'):
                if k in body:
                    vals[k] = body[k]
            if 'leave_type' in body:
                vals['leave_type_id'] = int(body['leave_type'])
            if vals:
                rec.write(vals)
            return _json_response(_ser_leave(rec))
        except Exception as e:
            return _error_response(str(e), 500)

    @http.route('/api/student-leaves/<int:lid>/approve', type='http', auth='public', methods=['POST'], csrf=False)
    @jwt_required
    def approve_leave(self, lid, **kw):
        try:
            rec = request.env['encoach.student.leave'].sudo().browse(lid)
            if not rec.exists():
                return _error_response('Not found', 404)
            from datetime import date
            rec.write({'state': 'approve', 'approve_date': str(date.today()), 'approved_by': request.env.uid})
            return _json_response(_ser_leave(rec))
        except Exception as e:
            return _error_response(str(e), 500)

    @http.route('/api/student-leaves/<int:lid>', type='http', auth='public', methods=['DELETE'], csrf=False)
    @jwt_required
    def delete_leave(self, lid, **kw):
        try:
            rec = request.env['encoach.student.leave'].sudo().browse(lid)
            if rec.exists():
                rec.unlink()
            return _json_response({'success': True})
        except Exception as e:
            return _error_response(str(e), 500)

    @http.route('/api/student-leaves/<int:lid>/reject', type='http', auth='public', methods=['POST'], csrf=False)
    @jwt_required
    def reject_leave(self, lid, **kw):
        try:
            rec = request.env['encoach.student.leave'].sudo().browse(lid)
            if not rec.exists():
                return _error_response('Not found', 404)
            rec.write({'state': 'refuse'})
            return _json_response(_ser_leave(rec))
        except Exception as e:
            return _error_response(str(e), 500)

    # ── Leave Types ──────────────────────────────────────────────────

    @http.route('/api/student-leave-types', type='http', auth='public', methods=['GET'], csrf=False)
    @jwt_required
    def list_leave_types(self, **kw):
        try:
            M = request.env['encoach.student.leave.type'].sudo()
            offset, limit, page = _paginate(kw)
            total = M.search_count([])
            recs = M.search([], offset=offset, limit=limit)
            items = [{'id': r.id, 'name': r.name} for r in recs]
            return _json_response({'items': items, 'data': items, 'total': total, 'page': page, 'size': limit})
        except Exception as e:
            return _error_response(str(e), 500)

    @http.route('/api/student-leave-types', type='http', auth='public', methods=['POST'], csrf=False)
    @jwt_required
    def create_leave_type(self, **kw):
        try:
            body = _get_json_body()
            rec = request.env['encoach.student.leave.type'].sudo().create({'name': body.get('name', '')})
            return _json_response({'id': rec.id, 'name': rec.name})
        except Exception as e:
            return _error_response(str(e), 500)
