from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
import requests
import json
import logging
import os
import asyncio
from prefect.deployments import run_deployment

_logger = logging.getLogger(__name__)


class KYC(models.Model):
    _name = 'kyc.request'
    _description = 'Marketplace KYC Request'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _order = 'create_date desc'

    name = fields.Char('Reference', required=True, copy=False, readonly=True, 
                      default=lambda self: _('New'))
    team_uuid = fields.Char('Team UUID', required=True, tracking=True)
    team_name = fields.Char('Team Name', required=True, tracking=True)
    owner_id = fields.Char('Owner ID', required=True)
    logto_org_id = fields.Char('Logto Organization ID', required=True)
    
    status = fields.Selection([
        ('pending', 'Pending Review'),
        ('in_review', 'In Review'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
        ('suspended', 'Suspended'),
    ], string='KYC Status', default='pending', tracking=True)
    
    score = fields.Integer('KYC Score', default=0, help="Score from 0 to 100")
    
    # Company Information
    company_name = fields.Char('Company Name')
    company_tax_number = fields.Char('Tax Number')
    company_registration = fields.Char('Registration Number')
    company_address = fields.Text('Company Address')
    
    # Documents
    documents = fields.Text('Documents', help="JSON array of document URLs")
    
    # Review Information
    reviewer_id = fields.Many2one('res.users', 'Reviewer', tracking=True)
    review_notes = fields.Html('Review Notes')
    reviewed_date = fields.Datetime('Review Date')
    
    # Dates
    submitted_date = fields.Datetime('Submitted Date')
    approved_date = fields.Datetime('Approved Date')
    
    # Integration fields
    prefect_task_id = fields.Char('Prefect Task ID', help="ID of the Prefect task for organization creation")
    organization_created = fields.Boolean('Organization Created', default=False, help="True when Logto organization has been created")
    
    # Computed fields
    can_create_orders = fields.Boolean('Can Create Orders', compute='_compute_can_create_orders', store=True)
    days_pending = fields.Integer('Days Pending', compute='_compute_days_pending')
    
    @api.model
    def create(self, vals):
        if vals.get('name', _('New')) == _('New'):
            vals['name'] = self.env['ir.sequence'].next_by_code('kyc.request') or _('New')
        
        if not vals.get('submitted_date'):
            vals['submitted_date'] = fields.Datetime.now()
            
        result = super().create(vals)
        result._send_status_update()
        return result
    
    def write(self, vals):
        old_status = self.status
        result = super().write(vals)
        
        # If status changed, send update
        if 'status' in vals and vals['status'] != old_status:
            self._send_status_update()
            
        # Set reviewed date when moving to approved/rejected
        if vals.get('status') in ['approved', 'rejected'] and not self.reviewed_date:
            self.reviewed_date = fields.Datetime.now()
            if vals.get('status') == 'approved':
                self.approved_date = fields.Datetime.now()
                
        return result
    
    @api.depends('status')
    def _compute_can_create_orders(self):
        for record in self:
            record.can_create_orders = record.status == 'approved'
    
    def _compute_days_pending(self):
        for record in self:
            if record.submitted_date:
                delta = fields.Datetime.now() - record.submitted_date
                record.days_pending = delta.days
            else:
                record.days_pending = 0
    
    def _send_status_update(self):
        """Send status update to Kestra workflow"""
        try:
            kestra_url = "http://kestra:8080/api/v1/executions/trigger/optovia.teams/kyc-status-update"
            
            payload = {
                "team_id": self.team_uuid,
                "logto_org_id": self.logto_org_id,
                "kyc_status": self.status,
                "kyc_score": self.score,
                "can_create_orders": self.can_create_orders
            }
            
            response = requests.post(
                kestra_url,
                json=payload,
                headers={'Content-Type': 'application/json'},
                timeout=10
            )
            
            if response.status_code == 200:
                _logger.info(f"Successfully sent KYC update for team {self.team_uuid}")
            else:
                _logger.error(f"Failed to send KYC update: {response.status_code} - {response.text}")
                
        except Exception as e:
            _logger.error(f"Error sending KYC status update: {e}")
    
    def action_start_review(self):
        self.write({
            'status': 'in_review',
            'reviewer_id': self.env.user.id
        })
        
    def action_approve(self):
        if self.score < 60:
            raise ValidationError(_("Score must be at least 60 to approve KYC"))
            
        self.write({
            'status': 'approved',
            'reviewer_id': self.env.user.id,
            'approved_date': fields.Datetime.now()
        })
        
        # Trigger organization creation in Prefect
        self._trigger_organization_creation()
        
    def action_reject(self):
        if not self.review_notes:
            raise ValidationError(_("Review notes are required when rejecting KYC"))
            
        self.write({
            'status': 'rejected',
            'reviewer_id': self.env.user.id
        })
    
    @api.constrains('score')
    def _check_score(self):
        for record in self:
            if not (0 <= record.score <= 100):
                raise ValidationError(_("KYC Score must be between 0 and 100"))
    
    def _trigger_organization_creation(self):
        """Trigger Prefect flow to create Logto organization"""
        
        async def _run_deployment():
            flow_run = await run_deployment(
                name="create-organization-after-kyc-approval/create-organization-after-kyc-approval",
                parameters={
                    "team_id": self.team_uuid,
                    "team_name": self.team_name,
                    "owner_id": self.owner_id,
                    "company_name": self.company_name or self.team_name
                }
            )
            return flow_run
        
        try:
            # Run async deployment in sync context
            flow_run = asyncio.run(_run_deployment())
            
            self.write({
                'prefect_task_id': flow_run.id,
                'organization_created': True
            })
            _logger.info(f"Started organization creation flow for KYC {self.name}: {flow_run.id}")
            
        except Exception as e:
            _logger.error(f"Error triggering organization creation: {e}")
            raise  # Поднимаем ошибку чтобы видеть проблему