from src.models.user import db
from datetime import datetime
from decimal import Decimal

class Invoice(db.Model):
    __tablename__ = 'invoices'
    
    id = db.Column(db.Integer, primary_key=True)
    
    # Información básica de la factura
    invoice_number = db.Column(db.String(50), nullable=False)  # Número interno del sistema
    ncf = db.Column(db.String(19), nullable=False)  # Número de Comprobante Fiscal (NCF)
    ncf_modified = db.Column(db.String(19))  # NCF modificado (si aplica)
    
    # Información del proveedor
    supplier_name = db.Column(db.String(200), nullable=False)
    supplier_rnc = db.Column(db.String(11), nullable=False)  # RNC del proveedor
    supplier_id_type = db.Column(db.String(10), default='RNC')  # Tipo de identificación
    
    # Fechas
    invoice_date = db.Column(db.Date, nullable=False)
    payment_date = db.Column(db.Date)
    
    # Montos (usando Decimal para precisión financiera)
    invoiced_amount = db.Column(db.Numeric(12, 2), nullable=False)  # Monto facturado
    itbis_invoiced = db.Column(db.Numeric(12, 2), default=0)  # ITBIS facturado
    itbis_retained = db.Column(db.Numeric(12, 2), default=0)  # ITBIS retenido
    itbis_perceived = db.Column(db.Numeric(12, 2), default=0)  # ITBIS percibido
    income_retention = db.Column(db.Numeric(12, 2), default=0)  # Retención de renta
    isr_perceived = db.Column(db.Numeric(12, 2), default=0)  # ISR percibido
    selective_consumption_tax = db.Column(db.Numeric(12, 2), default=0)  # Impuesto selectivo al consumo
    other_taxes = db.Column(db.Numeric(12, 2), default=0)  # Otros impuestos/tasas
    legal_tip = db.Column(db.Numeric(12, 2), default=0)  # Monto propina legal
    
    # Clasificación de gastos (según DGII)
    expense_type = db.Column(db.String(2), nullable=False)  # 01-11 según tipos oficiales
    expense_description = db.Column(db.String(200))  # Descripción del tipo de gasto
    
    # Estado y procesamiento
    status = db.Column(db.String(20), default='pending')  # pending, approved, rejected
    ocr_processed = db.Column(db.Boolean, default=False)
    ocr_confidence = db.Column(db.Float)  # Confianza del OCR (0-1)
    
    # Archivos
    image_path = db.Column(db.String(500))  # Ruta de la imagen original
    processed_image_path = db.Column(db.String(500))  # Ruta de la imagen procesada
    
    # Metadatos
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    processed_at = db.Column(db.DateTime)  # Fecha de procesamiento OCR
    approved_at = db.Column(db.DateTime)  # Fecha de aprobación
    
    # Relaciones
    company_id = db.Column(db.Integer, db.ForeignKey('companies.id'), nullable=False)
    created_by_user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    approved_by_user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    
    # Relaciones con usuarios
    created_by = db.relationship('User', foreign_keys=[created_by_user_id], backref='created_invoices')
    approved_by = db.relationship('User', foreign_keys=[approved_by_user_id], backref='approved_invoices')
    
    def __repr__(self):
        return f'<Invoice {self.invoice_number} - {self.supplier_name}>'
    
    def to_dict(self):
        return {
            'id': self.id,
            'invoice_number': self.invoice_number,
            'ncf': self.ncf,
            'ncf_modified': self.ncf_modified,
            'supplier_name': self.supplier_name,
            'supplier_rnc': self.supplier_rnc,
            'supplier_id_type': self.supplier_id_type,
            'invoice_date': self.invoice_date.isoformat() if self.invoice_date else None,
            'payment_date': self.payment_date.isoformat() if self.payment_date else None,
            'invoiced_amount': float(self.invoiced_amount) if self.invoiced_amount else 0,
            'itbis_invoiced': float(self.itbis_invoiced) if self.itbis_invoiced else 0,
            'itbis_retained': float(self.itbis_retained) if self.itbis_retained else 0,
            'itbis_perceived': float(self.itbis_perceived) if self.itbis_perceived else 0,
            'income_retention': float(self.income_retention) if self.income_retention else 0,
            'isr_perceived': float(self.isr_perceived) if self.isr_perceived else 0,
            'selective_consumption_tax': float(self.selective_consumption_tax) if self.selective_consumption_tax else 0,
            'other_taxes': float(self.other_taxes) if self.other_taxes else 0,
            'legal_tip': float(self.legal_tip) if self.legal_tip else 0,
            'expense_type': self.expense_type,
            'expense_description': self.expense_description,
            'status': self.status,
            'ocr_processed': self.ocr_processed,
            'ocr_confidence': self.ocr_confidence,
            'image_path': self.image_path,
            'processed_image_path': self.processed_image_path,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None,
            'processed_at': self.processed_at.isoformat() if self.processed_at else None,
            'approved_at': self.approved_at.isoformat() if self.approved_at else None,
            'company_id': self.company_id,
            'created_by_user_id': self.created_by_user_id,
            'approved_by_user_id': self.approved_by_user_id
        }
    
    def to_606_format(self):
        """Convierte la factura al formato requerido por el 606 de la DGII"""
        return {
            'rnc_proveedor': self.supplier_rnc,
            'tipo_identificacion': self.supplier_id_type,
            'ncf': self.ncf,
            'ncf_modificado': self.ncf_modified or '',
            'fecha_comprobante': self.invoice_date.strftime('%d/%m/%Y') if self.invoice_date else '',
            'fecha_pago': self.payment_date.strftime('%d/%m/%Y') if self.payment_date else '',
            'monto_facturado': float(self.invoiced_amount) if self.invoiced_amount else 0,
            'itbis_facturado': float(self.itbis_invoiced) if self.itbis_invoiced else 0,
            'itbis_retenido': float(self.itbis_retained) if self.itbis_retained else 0,
            'itbis_percibido': float(self.itbis_perceived) if self.itbis_perceived else 0,
            'retencion_renta': float(self.income_retention) if self.income_retention else 0,
            'isr_percibido': float(self.isr_perceived) if self.isr_perceived else 0,
            'impuesto_selectivo_consumo': float(self.selective_consumption_tax) if self.selective_consumption_tax else 0,
            'otros_impuestos': float(self.other_taxes) if self.other_taxes else 0,
            'monto_propina_legal': float(self.legal_tip) if self.legal_tip else 0,
            'tipo_bienes_servicios': self.expense_type
        }

