from odoo import http, _
from odoo.http import request
from odoo.addons.phone_validation.tools import phone_validation

import json
import random

class CreatePortalAccount(http.Controller):

    @http.route('/create/portal/account', type="http", auth="public", csrf=False, methods=['POST'], website=True)
    def create_portal_account(self, **kw):
        try:
            data = {}
            applicant_name = kw.get('applicant_name')
            applicant_relation = kw.get('relation_type')
            first_name = kw.get('first_name')
            second_name = kw.get('second_name')
            login = kw.get('otp_mobile_phone')
            email = kw.get('email')
            account_type = kw.get('account_type')
            relation_type = kw.get('relation_type')
            password  = str(random.randint(1000, 9999))

            # Validate required fields
            if not login:
                msg = _("Login is required.")
                data = {
                    'status': False,
                    'message': msg
                }
                return json.dumps(data)

            # Check if user already exists with the same otp_mobile_phone
            existing_user = request.env['res.users'].sudo().search([('login', '=', login)], limit=1)
            if existing_user:
                existing_partner = existing_user.partner_id
                is_family_or_beneficiary = existing_partner.is_family or existing_partner.is_benefit
                is_donor_vendor_sponsor = existing_partner.is_donor or existing_partner.is_sponsor_portal or existing_partner.is_vendor
                
                if is_family_or_beneficiary and account_type == 'donor':
                    message = _("This phone number is already registered as Family/Beneficiary and cannot be used for sponsor account!")
                elif is_donor_vendor_sponsor and account_type == 'family':
                    message = _("This phone number is already registered as Donor/Sponsor and cannot be used for family account!")
                else:
                    message = _('This phone number is already registered. Please use a different phone number.')
                data = {
                    'status': False,
                    'message': message
                }
                return json.dumps(data)
            
            country = request.env.company.country_id
            formatted_phone = phone_validation.phone_format(
                login, 
                country.code if country else None, 
                country.phone_code if country else None, 
                force_format='E164', 
                raise_exception=False).replace('+', '')

            # Create partner first
            Partner = request.env['res.partner'].sudo()
            partner_vals = {
                'name': f'{first_name} {second_name}',
                'email': email,
                'phone': formatted_phone,
            }
            partner = Partner.search([('phone', '=like', f'%{formatted_phone}')], limit=1)
            if not partner:
                partner = Partner.create(partner_vals)
            else:
                partner.write(partner_vals)

            # Create user and link to partner (no reset password)
            Users = request.env['res.users'].sudo()
            user = Users.with_context(no_reset_password=True).create({
                'name': partner.name,
                'login': login,
                'partner_id': partner.id,
                'active': True,
            })

            # Set partner account_type
            partner.set_partner_account_type(account_type)

            # Update user fields similar to create_user and original flow
            user.sudo().write({
                'password': password,
                'otp_mobile_phone': login,
                'email': email,
                'phone': formatted_phone,
                'mobile': formatted_phone,
            })
            # Make the user as portal
            user.sudo().write({
                'groups_id': [(3, request.env.ref('base.group_user', False).id)],
            })
            user.sudo().write({
                'groups_id': [(4, request.env.ref('base.group_portal', False).id)],
            })

            # Generate OTP and enable it
            user.generate_otp()
            user.otp_enabled = True
            
            grant_benefit = False
            # Only create a grant.benefit record for beneficiary/family account types
            if account_type in ('beneficiary', 'family'):
                benefit_data = {
                    'name': f'{first_name} {second_name}',
                    'father_name': first_name,
                    'father_family_name': second_name,
                    'sms_phone': login,
                    'email': email,
                    'is_from_portal': True,
                    'applicant_name': applicant_name,
                    'partner_id': partner.id,
                    'user_id': user.id,
                    'request_producer_relation': int(applicant_relation) if applicant_relation else False,
                }

                # Check relation type
                if relation_type and int(relation_type):
                    relation_record = request.env['relation.settings'].sudo().search([('id', '=', relation_type)], limit=1)
                    if relation_record:
                        benefit_data.update({'request_producer_relation': relation_record.id})

                # Create the grant.benefit record and let its create flow run
                grant_benefit = request.env['grant.benefit'].sudo().with_context(force_website=True, is_benefit=True).create(benefit_data)
            elif account_type == 'donor':
                partner.write({
                    'is_donor': True,
                    'is_sponsor_portal': True,
                })
            msg = _("Portal account created successfully. An OTP has been sent to your mobile phone.")
            # Return success response
            data = {
                'status': True,
                'message': msg,
                'user_id': user.id,
                'grant_benefit_id': grant_benefit.id if grant_benefit else False,
            }
            return json.dumps(data)

        except Exception as e:
            request.env.cr.rollback()
            # Handle errors
            data = {
                'status': False,
                'message': f'An error occurred: {str(e)}'
            }
            return json.dumps(data)

    @http.route('/validate_otp', type='http', auth="public", website=True)
    def validate_otp(self, **kw):
        user = request.env['res.users'].sudo().browse(int(kw.get('user_id')))
        otp = kw.get('otp')
        if user:
            is_valid = user.validate_otp(otp)
            if is_valid:
                user.sudo().write({'active': True})

                # Commit before authentication
                request.env.cr.commit()
                
                # Authenticate the user properly
                request.session.authenticate(request.db, user.login, otp)

                # Redirect to the desired link
                data = {
                    'status': True,
                    'url': '/web',
                }
                # Replace with your desired link
            else:
                message = _("Invalid OTP. Please try again.")
                # If OTP validation fails, return an error
                data = {
                    'status': False,
                    'message': message,
                }
            return request.make_response(json.dumps(data), headers={'Content-Type': 'application/json'})
