# app/models/approval.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 ApprovalWorkflow(db.Model):
    """گردش کار تایید"""
    __tablename__ = 'approval_workflows'
    __table_args__ = {'extend_existing': True}
    
    id = db.Column(db.Integer, primary_key=True)
    
    # اطلاعات تایید
    payment_release_id = db.Column(db.Integer, db.ForeignKey('payment_releases.id'), nullable=False)
    step = db.Column(db.String(20), nullable=False)  # manager, employer, admin
    
    # تایید کننده
    approved_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
    approved_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    # وضعیت و نظرات
    status = db.Column(db.String(20), default='pending')  # pending, approved, rejected, skipped
    comments = db.Column(db.Text, nullable=True)
    
    # اطلاعات تکمیلی
    ip_address = db.Column(db.String(45), nullable=True)
    user_agent = db.Column(db.String(300), nullable=True)
    
    # زمان‌ها
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # ========== روابط با نام‌های یکتا ==========
    
    # رابطه با PaymentRelease
    payment_release = db.relationship(
        'PaymentRelease',
        foreign_keys=[payment_release_id],
        backref='approval_workflows_ref'  # نام یکتا
    )
    
    # رابطه با User (Approver)
    approver = db.relationship(
        'User',
        foreign_keys=[approved_by],
        backref='user_approvals_ref'  # نام یکتا
    )
    
    # ========== متدها ==========
    
    @classmethod
    def create_approval(cls, payment_release_id, step, created_by=None):
        """ایجاد یک گام تایید جدید"""
        approval = cls(
            payment_release_id=payment_release_id,
            step=step,
            status='pending'
        )
        if created_by:
            approval.approved_by = created_by
        return approval
    
    def approve(self, user_id, comments=None):
        """تایید توسط کاربر"""
        if self.status != 'pending':
            raise ValueError(f"این درخواست قبلاً {self.status} شده است")
        
        self.status = 'approved'
        self.approved_by = user_id
        self.approved_at = datetime.utcnow()
        if comments:
            self.comments = comments
    
    def reject(self, user_id, comments=None):
        """رد توسط کاربر"""
        if self.status != 'pending':
            raise ValueError(f"این درخواست قبلاً {self.status} شده است")
        
        self.status = 'rejected'
        self.approved_by = user_id
        self.approved_at = datetime.utcnow()
        if comments:
            self.comments = comments
    
    def skip(self, user_id, comments=None):
        """رد شدن از تایید (در صورت عدم نیاز)"""
        self.status = 'skipped'
        self.approved_by = user_id
        self.approved_at = datetime.utcnow()
        if comments:
            self.comments = comments
    
    def is_pending(self):
        """بررسی در انتظار بودن"""
        return self.status == 'pending'
    
    def is_approved(self):
        """بررسی تایید شده بودن"""
        return self.status == 'approved'
    
    def is_rejected(self):
        """بررسی رد شده بودن"""
        return self.status == 'rejected'
    
    def get_step_display(self):
        """نمایش گام به فارسی"""
        step_map = {
            'manager': 'تایید مدیر پروژه',
            'employer': 'تایید کارفرما',
            'admin': 'تایید ادمین'
        }
        return step_map.get(self.step, self.step)
    
    def get_status_display(self):
        """نمایش وضعیت به فارسی"""
        status_map = {
            'pending': 'در انتظار',
            'approved': 'تایید شده',
            'rejected': 'رد شده',
            'skipped': 'رد شده'
        }
        return status_map.get(self.status, self.status)
    
    def get_color_class(self):
        """دریافت کلاس رنگ برای نمایش"""
        color_map = {
            'pending': 'warning',
            'approved': 'success',
            'rejected': 'danger',
            'skipped': 'secondary'
        }
        return color_map.get(self.status, 'secondary')
    
    def to_dict(self):
        """تبدیل به دیکشنری برای JSON"""
        return {
            'id': self.id,
            'payment_release_id': self.payment_release_id,
            'step': self.step,
            'step_display': self.get_step_display(),
            'status': self.status,
            'status_display': self.get_status_display(),
            'color_class': self.get_color_class(),
            'approved_by': self.approved_by,
            'approver_name': self.approver.fullname if self.approver else None,
            'approved_at': self.approved_at.strftime('%Y-%m-%d %H:%M:%S'),
            'comments': self.comments,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'is_pending': self.is_pending(),
            'is_approved': self.is_approved(),
            'is_rejected': self.is_rejected()
        }
    
    def __repr__(self):
        return f'<ApprovalWorkflow {self.id} - {self.step} - {self.status}>'


class ApprovalStep(db.Model):
    """مدل تعریف گام‌های تایید برای هر نوع فرآیند"""
    __tablename__ = 'approval_steps'
    __table_args__ = {'extend_existing': True}
    
    id = db.Column(db.Integer, primary_key=True)
    
    # نوع فرآیند
    process_type = db.Column(db.String(50), nullable=False)  # payment_release, contract, etc.
    
    # اطلاعات گام
    step_order = db.Column(db.Integer, nullable=False)  # ترتیب گام
    step_name = db.Column(db.String(50), nullable=False)  # manager, employer, admin
    step_title = db.Column(db.String(100), nullable=False)  # عنوان نمایشی
    
    # الزامات
    is_required = db.Column(db.Boolean, default=True)
    can_skip = db.Column(db.Boolean, default=False)
    
    # نقش‌های مجاز برای تایید
    allowed_roles = db.Column(db.String(200), nullable=True)  # comma separated: admin,manager
    
    # توضیحات
    description = db.Column(db.Text, nullable=True)
    
    # زمان‌ها
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    def __repr__(self):
        return f'<ApprovalStep {self.process_type} - {self.step_order} - {self.step_name}>'