# app/models/installment.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


class Installment(db.Model):
    """مدل اقساط پرداختی قرارداد"""
    __tablename__ = 'installments'
    __table_args__ = {'extend_existing': True}
    
    id = db.Column(db.Integer, primary_key=True)
    
    # رابطه با قرارداد
    contract_id = db.Column(db.Integer, db.ForeignKey('contracts.id'), nullable=False)
    
    # اطلاعات قسط
    installment_number = db.Column(db.Integer, nullable=False)
    amount = db.Column(db.Float, nullable=False)
    due_date = db.Column(db.Date, nullable=False)
    payment_date = db.Column(db.Date, nullable=True)
    tracking_code = db.Column(db.String(50), nullable=True)
    
    # وضعیت
    is_paid = db.Column(db.Boolean, default=False)
    status = db.Column(db.String(20), default='pending')  # pending, paid, overdue, cancelled
    
    # توضیحات
    notes = db.Column(db.Text, nullable=True)
    late_fee = db.Column(db.Float, default=0)  # جریمه دیرکرد
    
    # زمان‌ها
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # ========== روابط با نام‌های یکتا ==========
    
    # رابطه با Contract
    contract = db.relationship(
        'Contract',
        foreign_keys=[contract_id],
        backref='installments_list'  # نام یکتا
    )
    
    # ========== متدها ==========
    
    def mark_as_paid(self, payment_date=None, tracking_code=None):
        """علامت زدن قسط به عنوان پرداخت شده"""
        self.is_paid = True
        self.status = 'paid'
        if payment_date:
            self.payment_date = payment_date
        else:
            self.payment_date = datetime.now().date()
        if tracking_code:
            self.tracking_code = tracking_code
    
    def mark_as_overdue(self):
        """علامت زدن قسط به عنوان معوق"""
        self.status = 'overdue'
    
    def mark_as_cancelled(self, notes=None):
        """لغو قسط"""
        self.status = 'cancelled'
        if notes:
            self.notes = notes
    
    def is_overdue(self):
        """بررسی معوق بودن قسط"""
        return datetime.now().date() > self.due_date and not self.is_paid
    
    def get_status_display(self):
        """نمایش وضعیت به فارسی"""
        status_map = {
            'pending': 'در انتظار',
            'paid': 'پرداخت شده',
            'overdue': 'معوق',
            'cancelled': 'لغو شده'
        }
        return status_map.get(self.status, self.status)
    
    def get_amount_formatted(self):
        """دریافت مبلغ به صورت فرمت شده"""
        return f"{self.amount:,.0f}"
    
    def get_late_days(self):
        """دریافت تعداد روزهای تاخیر"""
        if self.is_paid and self.payment_date:
            return (self.payment_date - self.due_date).days
        elif self.is_overdue():
            return (datetime.now().date() - self.due_date).days
        return 0
    
    def calculate_late_fee(self, daily_rate=0.01):
        """محاسبه جریمه دیرکرد"""
        if self.is_overdue():
            days = self.get_late_days()
            self.late_fee = self.amount * (daily_rate / 100) * days
        return self.late_fee
    
    def to_dict(self):
        """تبدیل به دیکشنری برای JSON"""
        return {
            'id': self.id,
            'contract_id': self.contract_id,
            'installment_number': self.installment_number,
            'amount': self.amount,
            'amount_formatted': self.get_amount_formatted(),
            'due_date': self.due_date.strftime('%Y-%m-%d'),
            'payment_date': self.payment_date.strftime('%Y-%m-%d') if self.payment_date else None,
            'tracking_code': self.tracking_code,
            'is_paid': self.is_paid,
            'status': self.status,
            'status_display': self.get_status_display(),
            'is_overdue': self.is_overdue(),
            'late_days': self.get_late_days(),
            'late_fee': self.late_fee,
            'notes': self.notes,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S')
        }
    
    def __repr__(self):
        return f'<Installment {self.installment_number} - {self.amount} - {self.status}>'


# ============================================
# مدل پرداخت اقساط (InstallmentPayment)
# ============================================

class InstallmentPayment(db.Model):
    """مدل ثبت پرداخت اقساط"""
    __tablename__ = 'installment_payments'
    __table_args__ = {'extend_existing': True}
    
    id = db.Column(db.Integer, primary_key=True)
    
    # رابطه با قسط
    installment_id = db.Column(db.Integer, db.ForeignKey('installments.id'), nullable=False)
    
    # اطلاعات پرداخت
    amount = db.Column(db.Float, nullable=False)
    payment_date = db.Column(db.Date, nullable=False)
    payment_method = db.Column(db.String(50), default='bank_transfer')  # bank_transfer, cash, check
    
    # اطلاعات تراکنش
    tracking_code = db.Column(db.String(100), nullable=True)
    receipt_image = db.Column(db.String(200), nullable=True)
    
    # تایید
    is_verified = db.Column(db.Boolean, default=False)
    verified_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
    verified_at = db.Column(db.DateTime, nullable=True)
    
    # توضیحات
    description = db.Column(db.Text, nullable=True)
    
    # زمان‌ها
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    created_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
    
    # ========== روابط با نام‌های یکتا ==========
    
    # رابطه با Installment
    installment = db.relationship(
        'Installment',
        foreign_keys=[installment_id],
        backref='payments_list'  # نام یکتا
    )
    
    # رابطه با User (Verifier)
    verifier = db.relationship(
        'User',
        foreign_keys=[verified_by],
        backref='verified_installment_payments'  # نام یکتا
    )
    
    # رابطه با User (Creator)
    creator = db.relationship(
        'User',
        foreign_keys=[created_by],
        backref='created_installment_payments'  # نام یکتا
    )
    
    # ========== متدها ==========
    
    def verify(self, verifier_id):
        """تایید پرداخت قسط"""
        self.is_verified = True
        self.verified_by = verifier_id
        self.verified_at = datetime.utcnow()
        
        # بروزرسانی وضعیت قسط
        self.installment.mark_as_paid(
            payment_date=self.payment_date,
            tracking_code=self.tracking_code
        )
    
    def to_dict(self):
        """تبدیل به دیکشنری برای JSON"""
        return {
            'id': self.id,
            'installment_id': self.installment_id,
            'installment_number': self.installment.installment_number if self.installment else None,
            'amount': self.amount,
            'amount_formatted': f"{self.amount:,.0f}",
            'payment_date': self.payment_date.strftime('%Y-%m-%d'),
            'payment_method': self.payment_method,
            'tracking_code': self.tracking_code,
            'receipt_image': self.receipt_image,
            'is_verified': self.is_verified,
            'verifier_name': self.verifier.fullname if self.verifier else None,
            'verified_at': self.verified_at.strftime('%Y-%m-%d %H:%M:%S') if self.verified_at else None,
            'description': self.description,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S')
        }
    
    def __repr__(self):
        return f'<InstallmentPayment {self.id} - {self.amount} - {self.payment_date}>'