# app/models/check_transaction.py

from flask_login import UserMixin
from datetime import datetime
from app.extensions import db, login_manager
from werkzeug.security import generate_password_hash, check_password_hash
import random
import string
import json


class CheckTransaction(db.Model):
    """مدل تراکنش‌های چک الکترونیک"""
    __tablename__ = 'check_transactions'
    __table_args__ = {'extend_existing': True}
    
    id = db.Column(db.Integer, primary_key=True)
    
    # اطلاعات چک
    check_id = db.Column(db.Integer, db.ForeignKey('electronic_checks.id'), nullable=False)
    bank_check_id = db.Column(db.Integer, db.ForeignKey('bank_checks.id'), nullable=True)  # چک بانکی اختصاص داده شده
    
    # نوع تراکنش
    transaction_type = db.Column(db.String(20), nullable=False)  # issue, activate, cancel, expire, allocate, return, cash
    
    # اطلاعات مالی
    amount = db.Column(db.Float, nullable=True)
    before_status = db.Column(db.String(20), nullable=True)
    after_status = db.Column(db.String(20), nullable=True)
    
    # اطلاعات تکمیلی
    reason = db.Column(db.Text, nullable=True)
    description = db.Column(db.Text, nullable=True)
    reference_number = db.Column(db.String(50), nullable=True)  # شماره مرجع
    
    # مجری
    performed_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
    performed_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    # زمان
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    # ========== روابط با نام‌های یکتا ==========
    
    # رابطه با چک الکترونیک
    electronic_check = db.relationship(
        'ElectronicCheck',
        foreign_keys=[check_id],
        backref='check_transactions_list'  # نام یکتا
    )
    
    # رابطه با چک بانکی
    bank_check = db.relationship(
        'BankCheck',
        foreign_keys=[bank_check_id],
        backref='check_transactions_list'  # نام یکتا
    )
    
    # رابطه با کاربر انجام دهنده
    performer = db.relationship(
        'User',
        foreign_keys=[performed_by],
        backref='performed_check_transactions_list'  # نام یکتا
    )
    
    # ========== متدها ==========
    
    @classmethod
    def create_transaction(cls, check_id, transaction_type, amount=None, 
                          before_status=None, after_status=None, 
                          reason=None, description=None, performed_by=None,
                          bank_check_id=None, reference_number=None):
        """ایجاد تراکنش جدید"""
        transaction = cls(
            check_id=check_id,
            bank_check_id=bank_check_id,
            transaction_type=transaction_type,
            amount=amount,
            before_status=before_status,
            after_status=after_status,
            reason=reason,
            description=description,
            reference_number=reference_number,
            performed_by=performed_by
        )
        db.session.add(transaction)
        db.session.commit()
        return transaction
    
    @classmethod
    def log_issue(cls, check_id, amount, performed_by, description=None):
        """ثبت تراکنش صدور چک"""
        return cls.create_transaction(
            check_id=check_id,
            transaction_type='issue',
            amount=amount,
            before_status='pending',
            after_status='issued',
            description=description or 'صدور چک الکترونیک',
            performed_by=performed_by
        )
    
    @classmethod
    def log_activate(cls, check_id, performed_by, reason=None, description=None):
        """ثبت تراکنش فعالسازی چک"""
        return cls.create_transaction(
            check_id=check_id,
            transaction_type='activate',
            before_status='issued',
            after_status='active',
            reason=reason,
            description=description or 'فعالسازی چک',
            performed_by=performed_by
        )
    
    @classmethod
    def log_cancel(cls, check_id, performed_by, reason=None, description=None):
        """ثبت تراکنش ابطال چک"""
        return cls.create_transaction(
            check_id=check_id,
            transaction_type='cancel',
            before_status='issued',
            after_status='cancelled',
            reason=reason,
            description=description or 'ابطال چک',
            performed_by=performed_by
        )
    
    @classmethod
    def log_allocate(cls, check_id, bank_check_id, performed_by, description=None):
        """ثبت تراکنش اختصاص چک بانکی"""
        return cls.create_transaction(
            check_id=check_id,
            bank_check_id=bank_check_id,
            transaction_type='allocate',
            before_status='issued',
            after_status='allocated',
            description=description or 'اختصاص چک بانکی',
            performed_by=performed_by
        )
    
    @classmethod
    def log_cash(cls, check_id, performed_by, amount=None, description=None):
        """ثبت تراکنش نقد شدن چک"""
        return cls.create_transaction(
            check_id=check_id,
            transaction_type='cash',
            amount=amount,
            before_status='active',
            after_status='cashed',
            description=description or 'نقد شدن چک',
            performed_by=performed_by
        )
    
    @classmethod
    def log_expire(cls, check_id, performed_by, reason=None, description=None):
        """ثبت تراکنش انقضای چک"""
        return cls.create_transaction(
            check_id=check_id,
            transaction_type='expire',
            before_status='issued',
            after_status='expired',
            reason=reason,
            description=description or 'انقضای چک',
            performed_by=performed_by
        )
    
    @classmethod
    def log_return(cls, bank_check_id, performed_by, reason=None, description=None):
        """ثبت تراکنش بازگشت چک به بانک"""
        return cls.create_transaction(
            check_id=None,
            bank_check_id=bank_check_id,
            transaction_type='return',
            before_status='available',
            after_status='returned',
            reason=reason,
            description=description or 'بازگشت چک به بانک',
            performed_by=performed_by
        )
    
    def get_status_display(self):
        """نمایش وضعیت به فارسی"""
        status_map = {
            'issue': 'صدور',
            'activate': 'فعالسازی',
            'cancel': 'ابطال',
            'expire': 'انقضا',
            'allocate': 'اختصاص',
            'cash': 'نقد شدن',
            'return': 'بازگشت'
        }
        return status_map.get(self.transaction_type, self.transaction_type)
    
    def to_dict(self):
        """تبدیل به دیکشنری برای JSON"""
        return {
            'id': self.id,
            'check_id': self.check_id,
            'check_number': self.electronic_check.check_number if self.electronic_check else None,
            'bank_check_number': self.bank_check.check_number if self.bank_check else None,
            'transaction_type': self.transaction_type,
            'transaction_type_display': self.get_status_display(),
            'amount': self.amount,
            'amount_formatted': f"{self.amount:,.0f}" if self.amount else None,
            'before_status': self.before_status,
            'after_status': self.after_status,
            'reason': self.reason,
            'description': self.description,
            'reference_number': self.reference_number,
            'performer_id': self.performed_by,
            'performer_name': self.performer.fullname if self.performer else None,
            'performed_at': self.performed_at.strftime('%Y-%m-%d %H:%M:%S'),
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S')
        }
    
    def __repr__(self):
        return f'<CheckTransaction {self.id} - {self.transaction_type} - {self.amount}>'