from odoo import models, fields, api
import json
import logging
import requests
import uuid

_logger = logging.getLogger(__name__)


class LogisticsNode(models.Model):
    _name = 'logistics.node'
    _description = 'Logistics Node'
    _order = 'name'

    uuid = fields.Char(
        string='UUID',
        required=True,
        readonly=True,
        default=lambda self: str(uuid.uuid4()),
        help='Unique identifier for this node across all systems'
    )

    code = fields.Char(
        string='Code',
        index=True,
        help='UN/LOCODE or other standard code (e.g., KEMBA for Mombasa)'
    )

    name = fields.Char(
        string='Node Name',
        required=True,
        help='Name of the logistics node'
    )
    
    latitude = fields.Float(
        string='Latitude',
        required=True,
        digits=(10, 7),
        help='Latitude coordinates in decimal degrees'
    )
    
    longitude = fields.Float(
        string='Longitude', 
        required=True,
        digits=(10, 7),
        help='Longitude coordinates in decimal degrees'
    )
    
    country_id = fields.Many2one('res.country', string='Country', required=True)
    
    
    
    connection_ids = fields.One2many(
        'logistics.node.connection',
        'node_id',
        string='Connections',
        help='Available connection types for this node'
    )
    
    @api.depends('connection_ids.transport_category_id')
    def _compute_has_auto_connection(self):
        for record in self:
            record.has_auto_connection = any(
                conn.transport_category_id.code == 'auto' and conn.active 
                for conn in record.connection_ids if conn.transport_category_id
            )
    
    has_auto_connection = fields.Boolean(
        string='Has Auto Connection',
        compute='_compute_has_auto_connection',
        store=True
    )
    

    @api.model
    def create(self, vals):
        node = super().create(vals)
        return node
    
    def write(self, vals):
        result = super().write(vals)
        return result
    
    def _get_prefect_deployment_id(self):
        """Get or cache Prefect deployment ID for sync-node flow."""
        prefect_api_url = self.env['ir.config_parameter'].sudo().get_param(
            'prefect.api_url',
            default='http://prefect-server:4200/api'
        )

        # Get deployment by name
        response = requests.get(
            f"{prefect_api_url}/deployments/name/sync-node/sync-node-deployment",
            timeout=10
        )
        response.raise_for_status()
        return response.json()['id']

    def action_sync_to_maps(self):
        """Sync node to Optovia Maps via Prefect API"""
        prefect_api_url = self.env['ir.config_parameter'].sudo().get_param(
            'prefect.api_url',
            default='http://prefect-server:4200/api'
        )

        try:
            deployment_id = self._get_prefect_deployment_id()

            response = requests.post(
                f"{prefect_api_url}/deployments/{deployment_id}/create_flow_run",
                json={"parameters": {"node_uuid": self.uuid}},
                timeout=10
            )
            response.raise_for_status()
            flow_run = response.json()
            _logger.info(f"Node {self.uuid} sync triggered, flow_run_id: {flow_run['id']}")
        except requests.exceptions.RequestException as e:
            _logger.error(f"Failed to trigger node sync: {e}")
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'title': 'Optovia Maps',
                    'message': f'Failed to sync: {str(e)}',
                    'type': 'danger',
                }
            }

        return {
            'type': 'ir.actions.client',
            'tag': 'display_notification',
            'params': {
                'title': 'Optovia Maps',
                'message': 'Node sync started',
                'type': 'success',
            }
        }

    def action_sync_to_maps_batch(self):
        """Batch sync nodes to Optovia Maps via Prefect API"""
        prefect_api_url = self.env['ir.config_parameter'].sudo().get_param(
            'prefect.api_url',
            default='http://prefect-server:4200/api'
        )

        success_count = 0
        fail_count = 0

        try:
            deployment_id = self._get_prefect_deployment_id()
        except requests.exceptions.RequestException as e:
            _logger.error(f"Failed to get deployment ID: {e}")
            return {
                'type': 'ir.actions.client',
                'tag': 'display_notification',
                'params': {
                    'title': 'Optovia Maps Batch Sync',
                    'message': f'Failed to get deployment: {str(e)}',
                    'type': 'danger',
                }
            }

        for node in self:
            try:
                response = requests.post(
                    f"{prefect_api_url}/deployments/{deployment_id}/create_flow_run",
                    json={"parameters": {"node_uuid": node.uuid}},
                    timeout=10
                )
                response.raise_for_status()
                success_count += 1
            except requests.exceptions.RequestException as e:
                _logger.error(f"Failed to trigger node sync for {node.uuid}: {e}")
                fail_count += 1

        return {
            'type': 'ir.actions.client',
            'tag': 'display_notification',
            'params': {
                'title': 'Optovia Maps Batch Sync',
                'message': f'Queued {success_count} nodes, {fail_count} failed',
                'type': 'success' if fail_count == 0 else 'warning',
            }
        }
