# app/models/report.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 PhotoReport(db.Model):
    """مدل گزارش تصویری از پروژه"""
    __tablename__ = 'photo_reports'
    __table_args__ = {'extend_existing': True}
    
    id = db.Column(db.Integer, primary_key=True)
    
    # روابط کلیدی
    employee_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    project_id = db.Column(db.Integer, db.ForeignKey('projects.id'), nullable=False)
    
    # اطلاعات گزارش
    image_path = db.Column(db.String(200), nullable=False)
    gps_lat = db.Column(db.Float, nullable=False)
    gps_lon = db.Column(db.Float, nullable=False)
    gps_accuracy = db.Column(db.Float, nullable=True)  # دقت GPS
    
    description = db.Column(db.Text, 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)
    
    # زمان
    report_time = db.Column(db.DateTime, default=datetime.utcnow)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    # ========== روابط با نام‌های یکتا ==========
    
    # رابطه با User (Employee)
    employee = db.relationship(
        'User',
        foreign_keys=[employee_id],
        backref='user_photo_reports_list'  # نام یکتا
    )
    
    # رابطه با Project
    project = db.relationship(
        'Project',
        foreign_keys=[project_id],
        backref='photo_reports_list'  # نام یکتا
    )
    
    # رابطه با User (Verifier)
    verifier = db.relationship(
        'User',
        foreign_keys=[verified_by],
        backref='verified_photo_reports'  # نام یکتا
    )
    
    # ========== متدها ==========
    
    def verify(self, admin_id):
        """تایید گزارش توسط ادمین"""
        self.is_verified = True
        self.verified_by = admin_id
        self.verified_at = datetime.utcnow()
    
    def is_in_project_range(self, project):
        """بررسی اینکه آیا گزارش در محدوده پروژه است"""
        from math import radians, sin, cos, sqrt, atan2
        R = 6371000  # شعاع زمین به متر
        
        lat1, lon1 = radians(self.gps_lat), radians(self.gps_lon)
        lat2, lon2 = radians(project.gps_lat), radians(project.gps_lon)
        
        dlat = lat2 - lat1
        dlon = lon2 - lon1
        
        a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
        c = 2 * atan2(sqrt(a), sqrt(1-a))
        distance = R * c
        
        return distance <= project.gps_radius
    
    def to_dict(self):
        """تبدیل به دیکشنری برای JSON"""
        return {
            'id': self.id,
            'employee_id': self.employee_id,
            'employee_name': self.employee.fullname if self.employee else None,
            'project_id': self.project_id,
            'project_name': self.project.name if self.project else None,
            'image_path': self.image_path,
            'gps_lat': self.gps_lat,
            'gps_lon': self.gps_lon,
            'description': self.description,
            'is_verified': self.is_verified,
            'report_time': self.report_time.strftime('%Y-%m-%d %H:%M:%S'),
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S')
        }
    
    def __repr__(self):
        return f'<PhotoReport {self.id} - Project:{self.project_id} - Employee:{self.employee_id}>'


class Report(db.Model):
    """مدل گزارش‌های ارسالی به کارفرما و ادمین"""
    __tablename__ = 'reports'
    __table_args__ = {'extend_existing': True}
    
    id = db.Column(db.Integer, primary_key=True)
    
    # روابط کلیدی
    project_id = db.Column(db.Integer, db.ForeignKey('projects.id'), nullable=False)
    employer_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
    
    # اطلاعات گزارش
    report_type = db.Column(db.String(50), nullable=False)  # monthly, weekly, daily, custom
    title = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text, nullable=False)
    
    # وضعیت
    status = db.Column(db.String(20), default='pending')  # pending, reviewed, approved, rejected
    
    # بازخورد
    feedback = db.Column(db.Text, nullable=True)
    reviewed_at = db.Column(db.DateTime, nullable=True)
    reviewed_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
    
    # پیوست‌ها
    attachments = db.Column(db.JSON, nullable=True)  # لیست فایل‌های پیوست
    
    # زمان‌ها
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    created_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
    
    # ========== روابط با نام‌های یکتا ==========
    
    # رابطه با Project
    project = db.relationship(
        'Project',
        foreign_keys=[project_id],
        backref='reports_list'  # نام یکتا
    )
    
    # رابطه با User (Employer)
    employer = db.relationship(
        'User',
        foreign_keys=[employer_id],
        backref='employer_reports'  # نام یکتا
    )
    
    # رابطه با User (Reviewer)
    reviewer = db.relationship(
        'User',
        foreign_keys=[reviewed_by],
        backref='reviewed_reports'  # نام یکتا
    )
    
    # رابطه با User (Creator)
    creator = db.relationship(
        'User',
        foreign_keys=[created_by],
        backref='created_reports'  # نام یکتا
    )
    
    # ========== متدها ==========
    
    def review(self, user_id, feedback=None):
        """بررسی گزارش توسط کاربر"""
        self.status = 'reviewed'
        self.reviewed_at = datetime.utcnow()
        self.reviewed_by = user_id
        if feedback:
            self.feedback = feedback
    
    def approve(self, user_id, feedback=None):
        """تایید گزارش"""
        self.status = 'approved'
        self.reviewed_at = datetime.utcnow()
        self.reviewed_by = user_id
        if feedback:
            self.feedback = feedback
    
    def reject(self, user_id, feedback=None):
        """رد گزارش"""
        self.status = 'rejected'
        self.reviewed_at = datetime.utcnow()
        self.reviewed_by = user_id
        if feedback:
            self.feedback = feedback
    
    def get_status_display(self):
        """نمایش وضعیت به فارسی"""
        status_map = {
            'pending': 'در انتظار',
            'reviewed': 'بررسی شده',
            'approved': 'تایید شده',
            'rejected': 'رد شده'
        }
        return status_map.get(self.status, self.status)
    
    def get_type_display(self):
        """نمایش نوع گزارش به فارسی"""
        type_map = {
            'monthly': 'ماهانه',
            'weekly': 'هفتگی',
            'daily': 'روزانه',
            'custom': 'سفارشی'
        }
        return type_map.get(self.report_type, self.report_type)
    
    def to_dict(self):
        """تبدیل به دیکشنری برای JSON"""
        return {
            'id': self.id,
            'project_id': self.project_id,
            'project_name': self.project.name if self.project else None,
            'employer_id': self.employer_id,
            'employer_name': self.employer.fullname if self.employer else None,
            'report_type': self.report_type,
            'report_type_display': self.get_type_display(),
            'title': self.title,
            'content': self.content,
            'status': self.status,
            'status_display': self.get_status_display(),
            'feedback': self.feedback,
            'attachments': self.attachments,
            'reviewed_at': self.reviewed_at.strftime('%Y-%m-%d %H:%M:%S') if self.reviewed_at else None,
            'reviewer_name': self.reviewer.fullname if self.reviewer else None,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'creator_name': self.creator.fullname if self.creator else None
        }
    
    def __repr__(self):
        return f'<Report {self.id} - {self.title} - {self.status}>'


class ReportTemplate(db.Model):
    """مدل قالب‌های گزارش"""
    __tablename__ = 'report_templates'
    __table_args__ = {'extend_existing': True}
    
    id = db.Column(db.Integer, primary_key=True)
    
    # اطلاعات قالب
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text, nullable=True)
    report_type = db.Column(db.String(50), nullable=False)  # monthly, weekly, daily, custom
    
    # محتوای قالب
    template_content = db.Column(db.Text, nullable=False)
    template_variables = db.Column(db.JSON, nullable=True)  # متغیرهای قابل جایگزینی
    
    # وضعیت
    is_active = db.Column(db.Boolean, default=True)
    is_default = db.Column(db.Boolean, default=False)
    
    # زمان‌ها
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    created_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # ========== روابط با نام‌های یکتا ==========
    
    # رابطه با User (Creator)
    creator = db.relationship(
        'User',
        foreign_keys=[created_by],
        backref='created_report_templates'  # نام یکتا
    )
    
    def __repr__(self):
        return f'<ReportTemplate {self.id} - {self.name}>'


class ReportSchedule(db.Model):
    """مدل زمان‌بندی گزارش‌های خودکار"""
    __tablename__ = 'report_schedules'
    __table_args__ = {'extend_existing': True}
    
    id = db.Column(db.Integer, primary_key=True)
    
    # روابط کلیدی
    project_id = db.Column(db.Integer, db.ForeignKey('projects.id'), nullable=False)
    template_id = db.Column(db.Integer, db.ForeignKey('report_templates.id'), nullable=False)
    
    # اطلاعات زمان‌بندی
    schedule_type = db.Column(db.String(20), nullable=False)  # daily, weekly, monthly
    schedule_time = db.Column(db.Time, nullable=False)
    schedule_days = db.Column(db.JSON, nullable=True)  # برای هفتگی: [0,1,2,3,4,5,6]
    schedule_day_of_month = db.Column(db.Integer, nullable=True)  # برای ماهانه: 1-31
    
    # وضعیت
    is_active = db.Column(db.Boolean, default=True)
    last_run_at = db.Column(db.DateTime, nullable=True)
    next_run_at = db.Column(db.DateTime, nullable=True)
    
    # زمان‌ها
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    created_by = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
    
    # ========== روابط با نام‌های یکتا ==========
    
    # رابطه با Project
    project = db.relationship(
        'Project',
        foreign_keys=[project_id],
        backref='report_schedules'  # نام یکتا
    )
    
    # رابطه با ReportTemplate
    template = db.relationship(
        'ReportTemplate',
        foreign_keys=[template_id],
        backref='schedules'  # نام یکتا
    )
    
    # رابطه با User (Creator)
    creator = db.relationship(
        'User',
        foreign_keys=[created_by],
        backref='created_report_schedules'  # نام یکتا
    )
    
    def get_schedule_type_display(self):
        """نمایش نوع زمان‌بندی به فارسی"""
        type_map = {
            'daily': 'روزانه',
            'weekly': 'هفتگی',
            'monthly': 'ماهانه'
        }
        return type_map.get(self.schedule_type, self.schedule_type)
    
    def get_next_run(self):
        """محاسبه زمان بعدی اجرا"""
        # این متد باید بر اساس منطق زمان‌بندی پیاده‌سازی شود
        pass
    
    def to_dict(self):
        """تبدیل به دیکشنری برای JSON"""
        return {
            'id': self.id,
            'project_id': self.project_id,
            'project_name': self.project.name if self.project else None,
            'template_id': self.template_id,
            'template_name': self.template.name if self.template else None,
            'schedule_type': self.schedule_type,
            'schedule_type_display': self.get_schedule_type_display(),
            'schedule_time': self.schedule_time.strftime('%H:%M') if self.schedule_time else None,
            'schedule_days': self.schedule_days,
            'schedule_day_of_month': self.schedule_day_of_month,
            'is_active': self.is_active,
            'last_run_at': self.last_run_at.strftime('%Y-%m-%d %H:%M:%S') if self.last_run_at else None,
            'next_run_at': self.next_run_at.strftime('%Y-%m-%d %H:%M:%S') if self.next_run_at else None,
            'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'creator_name': self.creator.fullname if self.creator else None
        }
    
    def __repr__(self):
        return f'<ReportSchedule {self.id} - {self.schedule_type} - Project:{self.project_id}>'