# apps/leave_form_app/models.py

from datetime import datetime
from sqlalchemy import (
    Column,
    Integer,
    String,
    Date,
    DateTime,
    Text,
    ForeignKey,
)
from sqlalchemy.orm import relationship

from config.db import Base


class LeaveUser(Base):
    __tablename__ = "leave_users"

    id = Column(Integer, primary_key=True, autoincrement=True)
    username = Column(String(64), unique=True, nullable=False)
    full_name = Column(String(128), nullable=False)
    email = Column(String(255), nullable=False)
    role = Column(String(32), nullable=False)  # "employee", "manager", "admin"
    reports_to = Column(String(64), nullable=True)  # username del manager

    def to_dict(self):
        return {
            "id": self.id,
            "username": self.username,
            "full_name": self.full_name,
            "email": self.email,
            "role": self.role,
            "reports_to": self.reports_to,
        }


class LeaveRequest(Base):
    __tablename__ = "leave_requests"

    id = Column(Integer, primary_key=True, autoincrement=True)

    # Quién pide el leave
    employee_username = Column(String(64), nullable=False)
    employee_name = Column(String(128), nullable=True)
    employee_role = Column(String(64), nullable=True)

    # Manager asignado a revisar este leave
    manager_username = Column(String(64), nullable=True)
    manager_comment = Column(Text, nullable=True)

    # Detalles del leave
    type = Column(String(32), nullable=False)   # annual, sick, rdo, unpaid, etc.
    reason = Column(String(255), nullable=True)

    start_date = Column(Date, nullable=False)
    end_date = Column(Date, nullable=False)
    duration = Column(String(32), nullable=False)  # full, half_am, half_pm, etc.

    contact = Column(String(255), nullable=True)

    # Estado del flujo
    status = Column(String(32), nullable=False, default="pending")
    approved_by = Column(String(64), nullable=True)
    approved_at = Column(DateTime, nullable=True)

    # 🔥 IMPORTANTE: timestamps con defaults en Python
    created_at = Column(
        DateTime,
        nullable=False,
        default=datetime.utcnow,   # SQLAlchemy genera valor en Python
    )
    updated_at = Column(
        DateTime,
        nullable=False,
        default=datetime.utcnow,
        onupdate=datetime.utcnow,
    )

    approvals = relationship(
        "LeaveApproval",
        back_populates="leave",
        cascade="all, delete-orphan",
    )

    notifications = relationship(
        "LeaveNotification",
        back_populates="leave",
        cascade="all, delete-orphan",
    )

    def to_dict(self):
        return {
            "id": self.id,
            "employee_username": self.employee_username,
            "employee_name": self.employee_name,
            "employee_role": self.employee_role,
            "manager_username": self.manager_username,
            "manager_comment": self.manager_comment,
            "type": self.type,
            "reason": self.reason,
            "start_date": (
                self.start_date.isoformat() if self.start_date else None
            ),
            "end_date": (
                self.end_date.isoformat() if self.end_date else None
            ),
            "duration": self.duration,
            "contact": self.contact,
            "status": self.status,
            "approved_by": self.approved_by,
            "approved_at": (
                self.approved_at.isoformat(timespec="seconds")
                if self.approved_at
                else None
            ),
            "created_at": (
                self.created_at.isoformat(timespec="seconds")
                if self.created_at
                else None
            ),
            "updated_at": (
                self.updated_at.isoformat(timespec="seconds")
                if self.updated_at
                else None
            ),
        }


class LeaveApproval(Base):
    __tablename__ = "leave_approvals"

    id = Column(Integer, primary_key=True, autoincrement=True)
    leave_id = Column(Integer, ForeignKey("leave_requests.id"), nullable=False)

    actor_username = Column(String(64), nullable=False)  # quien aprueba/rechaza
    actor_role = Column(String(32), nullable=False)      # manager/admin
    action = Column(String(16), nullable=False)          # "approved" / "rejected"
    comment = Column(Text, nullable=True)
    created_at = Column(DateTime, nullable=False, default=datetime.utcnow)

    leave = relationship("LeaveRequest", back_populates="approvals")

    def to_dict(self):
        return {
            "id": self.id,
            "leave_id": self.leave_id,
            "actor_username": self.actor_username,
            "actor_role": self.actor_role,
            "action": self.action,
            "comment": self.comment,
            "created_at": (
                self.created_at.isoformat(timespec="seconds")
                if self.created_at
                else None
            ),
        }


class LeaveNotification(Base):
    __tablename__ = "leave_notifications"

    id = Column(Integer, primary_key=True, autoincrement=True)
    leave_id = Column(Integer, ForeignKey("leave_requests.id"), nullable=False)

    recipient_email = Column(String(255), nullable=False)
    type = Column(String(32), nullable=False)  # "submitted", "approved", "rejected"
    status = Column(String(32), nullable=False, default="pending")  # pending/sent/error
    error_message = Column(Text, nullable=True)
    created_at = Column(DateTime, nullable=False, default=datetime.utcnow)

    leave = relationship("LeaveRequest", back_populates="notifications")

    def to_dict(self):
        return {
            "id": self.id,
            "leave_id": self.leave_id,
            "recipient_email": self.recipient_email,
            "type": self.type,
            "status": self.status,
            "error_message": self.error_message,
            "created_at": (
                self.created_at.isoformat(timespec="seconds")
                if self.created_at
                else None
            ),
        }
