# -*- coding: utf-8 -*-
# Copyright 2024-2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)

import base64
import json
import logging

from odoo import http, fields, _
from odoo.http import request

_logger = logging.getLogger(__name__)


class Page11PublicSignController(http.Controller):

    def _get_sign_request(self, token):
        """Look up and validate a signing request by token."""
        req = request.env['fusion.page11.sign.request'].sudo().search([
            ('access_token', '=', token),
        ], limit=1)
        if not req:
            return None, 'not_found'
        if req.state == 'signed':
            return req, 'already_signed'
        if req.state == 'cancelled':
            return req, 'cancelled'
        if req.state == 'expired' or (
            req.expiry_date and req.expiry_date < fields.Datetime.now()
        ):
            if req.state != 'expired':
                req.state = 'expired'
            return req, 'expired'
        return req, 'ok'

    @http.route('/page11/sign/<string:token>', type='http', auth='public',
                website=True, sitemap=False)
    def page11_sign_form(self, token, **kw):
        """Display the Page 11 signing form."""
        sign_req, status = self._get_sign_request(token)

        if status == 'not_found':
            return request.render(
                'fusion_authorizer_portal.portal_page11_sign_invalid', {}
            )

        if status in ('expired', 'cancelled'):
            return request.render(
                'fusion_authorizer_portal.portal_page11_sign_expired',
                {'sign_request': sign_req},
            )

        if status == 'already_signed':
            return request.render(
                'fusion_authorizer_portal.portal_page11_sign_success',
                {'sign_request': sign_req, 'token': token},
            )

        order = sign_req.sale_order_id
        partner = order.partner_id

        assessment = request.env['fusion.assessment'].sudo().search([
            ('sale_order_id', '=', order.id),
        ], limit=1, order='create_date desc')

        ICP = request.env['ir.config_parameter'].sudo()
        google_maps_api_key = ICP.get_param('fusion_claims.google_maps_api_key', '')

        client_first_name = ''
        client_last_name = ''
        client_middle_name = ''
        client_health_card = ''
        client_health_card_version = ''

        if assessment:
            client_first_name = assessment.client_first_name or ''
            client_last_name = assessment.client_last_name or ''
            client_middle_name = assessment.client_middle_name or ''
            client_health_card = assessment.client_health_card or ''
            client_health_card_version = assessment.client_health_card_version or ''
        else:
            first, last = order._get_client_name_parts()
            client_first_name = first
            client_last_name = last

        values = {
            'sign_request': sign_req,
            'order': order,
            'partner': partner,
            'assessment': assessment,
            'company': order.company_id,
            'token': token,
            'signer_type': sign_req.signer_type,
            'is_agent': sign_req.signer_type != 'client',
            'google_maps_api_key': google_maps_api_key,
            'client_first_name': client_first_name,
            'client_last_name': client_last_name,
            'client_middle_name': client_middle_name,
            'client_health_card': client_health_card,
            'client_health_card_version': client_health_card_version,
        }
        return request.render(
            'fusion_authorizer_portal.portal_page11_public_sign', values,
        )

    @http.route('/page11/sign/<string:token>/submit', type='http',
                auth='public', methods=['POST'], website=True,
                csrf=True, sitemap=False)
    def page11_sign_submit(self, token, **post):
        """Process the submitted Page 11 signature."""
        sign_req, status = self._get_sign_request(token)

        if status != 'ok':
            return request.redirect(f'/page11/sign/{token}')

        signature_data = post.get('signature_data', '')
        if not signature_data:
            return request.redirect(f'/page11/sign/{token}?error=no_signature')

        if signature_data.startswith('data:image'):
            signature_data = signature_data.split(',', 1)[1]

        consent_accepted = post.get('consent_declaration', '') == 'on'
        if not consent_accepted:
            return request.redirect(f'/page11/sign/{token}?error=no_consent')

        signer_name = post.get('signer_name', sign_req.signer_name or '')
        chosen_signer_type = post.get('signer_type', sign_req.signer_type or 'client')
        consent_signed_by = 'applicant' if chosen_signer_type == 'client' else 'agent'

        signer_type_labels = {
            'spouse': 'Spouse', 'parent': 'Parent',
            'legal_guardian': 'Legal Guardian',
            'poa': 'Power of Attorney',
            'public_trustee': 'Public Trustee',
        }

        vals = {
            'signature_data': signature_data,
            'signer_name': signer_name,
            'signer_type': chosen_signer_type,
            'consent_declaration_accepted': True,
            'consent_signed_by': consent_signed_by,
            'signed_date': fields.Datetime.now(),
            'state': 'signed',
            'client_first_name': post.get('client_first_name', ''),
            'client_last_name': post.get('client_last_name', ''),
            'client_health_card': post.get('client_health_card', ''),
            'client_health_card_version': post.get('client_health_card_version', ''),
        }

        if consent_signed_by == 'agent':
            vals.update({
                'agent_first_name': post.get('agent_first_name', ''),
                'agent_last_name': post.get('agent_last_name', ''),
                'agent_middle_initial': post.get('agent_middle_initial', ''),
                'agent_phone': post.get('agent_phone', ''),
                'agent_unit': post.get('agent_unit', ''),
                'agent_street_number': post.get('agent_street_number', ''),
                'agent_street': post.get('agent_street', ''),
                'agent_city': post.get('agent_city', ''),
                'agent_province': post.get('agent_province', 'Ontario'),
                'agent_postal_code': post.get('agent_postal_code', ''),
                'signer_relationship': signer_type_labels.get(chosen_signer_type, chosen_signer_type),
            })

        sign_req.sudo().write(vals)

        try:
            sign_req.sudo()._generate_signed_pdf()
        except Exception as e:
            _logger.error("PDF generation failed for sign request %s: %s", sign_req.id, e)

        try:
            sign_req.sudo()._update_sale_order()
        except Exception as e:
            _logger.error("Sale order update failed for sign request %s: %s", sign_req.id, e)

        return request.render(
            'fusion_authorizer_portal.portal_page11_sign_success',
            {'sign_request': sign_req, 'token': token},
        )

    @http.route('/page11/sign/<string:token>/download', type='http',
                auth='public', website=True, sitemap=False)
    def page11_download_pdf(self, token, **kw):
        """Download the signed Page 11 PDF."""
        sign_req = request.env['fusion.page11.sign.request'].sudo().search([
            ('access_token', '=', token),
            ('state', '=', 'signed'),
        ], limit=1)

        if not sign_req or not sign_req.signed_pdf:
            return request.redirect(f'/page11/sign/{token}')

        pdf_content = base64.b64decode(sign_req.signed_pdf)
        filename = sign_req.signed_pdf_filename or 'Page11_Signed.pdf'

        return request.make_response(
            pdf_content,
            headers=[
                ('Content-Type', 'application/pdf'),
                ('Content-Disposition', f'attachment; filename="{filename}"'),
                ('Content-Length', str(len(pdf_content))),
            ],
        )
