# -*- coding: utf-8 -*-
import base64
import logging
from datetime import datetime
from odoo import http, fields, _, exceptions
from odoo.http import request
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager

_logger = logging.getLogger(__name__)

def parse_html_datetime(dt_str):
    if not dt_str:
        return None
    for fmt in (
        "%Y-%m-%dT%H:%M", "%Y-%m-%dT%H:%M:%S", 
        "%Y-%m-%d %H:%M:%S", "%Y-%m-%d %H:%M", "%Y-%m-%d",
        "%m/%d/%Y %I:%M %p", "%d/%m/%Y %I:%M %p",
        "%m/%d/%Y %H:%M", "%d/%m/%Y %H:%M",
        "%m/%d/%Y", "%d/%m/%Y"
    ):
        try:
            return datetime.strptime(dt_str.strip(), fmt)
        except ValueError:
            continue
    try:
        return fields.Datetime.to_datetime(dt_str)
    except Exception:
        return None

class EventRentalController(http.Controller):

    @http.route('/rentals', type='http', auth='public', website=True)
    def rental_catalog(self, search='', category=None, **post):
        domain = [('is_rental', '=', True)]
        if search:
            domain.append(('name', 'ilike', search))
        
        # Fetch products matching domain
        products = request.env['product.template'].sudo().search(domain)
        
        # Extract categories represented by these products to display in the filter sidebar
        categories = products.mapped('categ_id')
        
        if category:
            domain.append(('categ_id', '=', int(category)))
            products = request.env['product.template'].sudo().search(domain)
            
        values = {
            'products': products,
            'categories': categories,
            'search': search,
            'current_category': int(category) if category else None,
        }
        return request.render('event_rental.rental_catalog_template', values)

    @http.route('/rentals/<string:product_slug>', type='http', auth='public', website=True)
    def rental_product_detail(self, product_slug, **post):
        try:
            if '-' in product_slug:
                product_id = int(product_slug.split('-')[-1])
            else:
                product_id = int(product_slug)
        except (ValueError, IndexError):
            return request.not_found()

        product = request.env['product.template'].sudo().browse(product_id)
        if not product or not product.exists() or not product.is_rental:
            return request.not_found()

        return request.render('event_rental.rental_product_detail_template', {'product': product})

    @http.route('/rental/request', type='http', auth='public', website=True, methods=['GET', 'POST'])
    def rental_request(self, product_id=None, **post):
        if request.httprequest.method == 'GET':
            selected_product = None
            if product_id:
                # Browse product product variant
                product_tmpl = request.env['product.template'].sudo().browse(int(product_id))
                selected_product = product_tmpl.product_variant_id
            all_products = request.env['product.product'].sudo().search([('is_rental', '=', True)])
            return request.render('event_rental.rental_request_form_template', {
                'all_products': all_products,
                'selected_product': selected_product,
                'error_message': None,
                'post': post
            })
            
        # Process POST request
        try:
            _logger.info("RENTAL REQUEST POST PARAMS (product_id=%s): %s", product_id, post)
            customer_name = post.get('customer_name')
            customer_email = post.get('customer_email')
            customer_phone = post.get('customer_phone')
            company_name = post.get('company_name')
            customer_address = post.get('customer_address')
            
            start_date_str = post.get('start_date')
            end_date_str = post.get('end_date')
            location = post.get('location')
            event_type = post.get('event_type')
            
            req_product_id = int(product_id or post.get('product_id') or 0)
            quantity = float(post.get('quantity') or 1.0)
            doc_type = post.get('doc_type', 'aadhaar')
            id_proof_file = request.httprequest.files.get('id_proof')
            
            # Simple UI checks
            if not customer_name or not customer_email or not customer_phone or not start_date_str or not end_date_str or not location or not req_product_id:
                raise ValueError(_("All required fields must be filled."))
            
            if not id_proof_file or id_proof_file.filename == '':
                raise ValueError(_("Please upload a valid Government ID Proof document."))

            start_date = parse_html_datetime(start_date_str)
            end_date = parse_html_datetime(end_date_str)
            
            if not start_date or not end_date:
                raise ValueError(_("Invalid start or end date format."))
            
            if start_date >= end_date:
                raise ValueError(_("Event Start Date must be earlier than End Date."))
                
            product = request.env['product.product'].sudo().browse(req_product_id)
            if not product:
                raise ValueError(_("Invalid rental product selected."))
            
            # Availability checking bypassed per request
            # dummy_request = request.env['event.rental.request'].sudo()
            # available_qty = dummy_request.check_availability(start_date, end_date, product)
            # 
            # if available_qty < quantity:
            #     raise ValueError(_("Product '%s' is not available in the quantity requested (%s) for the selected dates. Only %s units are currently available.") % (
            #         product.name, quantity, available_qty
            #     ))
                
            # Find or create partner
            partner = request.env['res.partner'].sudo().search([('email', '=', customer_email)], limit=1)
            if not partner:
                partner = request.env['res.partner'].sudo().create({
                    'name': customer_name,
                    'email': customer_email,
                    'phone': customer_phone,
                    'company_name': company_name,
                    'street': customer_address,
                })
                
            # Create rental request record
            rental_request = request.env['event.rental.request'].sudo().create({
                'partner_id': partner.id,
                'customer_name': customer_name,
                'customer_email': customer_email,
                'customer_phone': customer_phone,
                'company_name': company_name,
                'customer_address': customer_address,
                'start_date': start_date,
                'end_date': end_date,
                'location': location,
                'event_type': event_type,
                'status': 'under_review',
            })
            
            # Create request line
            request.env['event.rental.line'].sudo().create({
                'request_id': rental_request.id,
                'product_id': product.id,
                'quantity': quantity,
            })
            
            # Store ID proof attachment
            file_content = id_proof_file.read()
            file_base64 = base64.b64encode(file_content)
            attachment = request.env['ir.attachment'].sudo().create({
                'name': id_proof_file.filename,
                'type': 'binary',
                'datas': file_base64,
                'res_model': 'event.rental.request',
                'res_id': rental_request.id,
            })
            
            # Create document record
            request.env['event.document'].sudo().create({
                'request_id': rental_request.id,
                'partner_id': partner.id,
                'doc_type': doc_type,
                'attachment_id': attachment.id,
                'verification_status': 'pending',
            })
            
            # Post submission trace
            rental_request.message_post(body=_("Rental request submitted successfully from public website."))
            
            return request.redirect(f'/rental/request/success?name={rental_request.name}')
            
        except Exception as e:
            selected_product = None
            if post.get('product_id'):
                selected_product = request.env['product.product'].sudo().browse(int(post.get('product_id')))
            all_products = request.env['product.product'].sudo().search([('is_rental', '=', True)])
            return request.render('event_rental.rental_request_form_template', {
                'all_products': all_products,
                'selected_product': selected_product,
                'error_message': str(e),
                'post': post
            })

    @http.route('/rental/request/success', type='http', auth='public', website=True)
    def rental_request_success(self, name, **post):
        return request.render('event_rental.rental_request_success_template', {'name': name})


class CustomerPortalRental(CustomerPortal):

    def _prepare_home_portal_values(self, counters):
        values = super()._prepare_home_portal_values(counters)
        if 'rental_count' in counters:
            partner = request.env.user.partner_id
            rental_count = request.env['event.rental.request'].search_count([
                ('partner_id', '=', partner.id)
            ])
            values['rental_count'] = rental_count
        return values

    @http.route(['/my/rentals', '/my/rentals/page/<int:page>'], type='http', auth="user", website=True)
    def portal_my_rentals(self, page=1, date_begin=None, date_end=None, sortby=None, **kw):
        values = self._prepare_portal_layout_values()
        partner = request.env.user.partner_id
        RentalRequest = request.env['event.rental.request']
        domain = [('partner_id', '=', partner.id)]
        
        # Count for pagination
        rental_count = RentalRequest.search_count(domain)
        pager = portal_pager(
            url="/my/rentals",
            total=rental_count,
            page=page,
            step=10
        )
        
        requests = RentalRequest.search(domain, limit=10, offset=pager['offset'])
        
        values.update({
            'requests': requests,
            'page_name': 'rental_requests',
            'pager': pager,
            'default_url': '/my/rentals',
        })
        return request.render("event_rental.portal_my_rental_requests", values)

    @http.route(['/my/rentals/<int:request_id>'], type='http', auth="user", website=True)
    def portal_rental_request_detail(self, request_id, **kw):
        rental_request = request.env['event.rental.request'].browse(request_id)
        try:
            # Enforce native record rules / access rights
            rental_request.check_access_rights('read')
            rental_request.check_access_rule('read')
        except exceptions.AccessError:
            return request.redirect('/my')
            
        values = {
            'rental_request': rental_request,
            'page_name': 'rental_request_detail',
        }
        return request.render("event_rental.portal_rental_request_detail_template", values)
