from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String, Float, Date, Time, ForeignKey, Enum, Text, Boolean, DateTime
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from datetime import datetime

# Inicializar SQLAlchemy
db = SQLAlchemy()

class Mascota(db.Model):
    __tablename__ = 'mascotas'

    id = Column(Integer, primary_key=True)
    # Datos básicos de la mascota
    nombre = Column(String(100), nullable=False)
    raza = Column(String(100))
    edad = Column(Integer)
    cumpleanos = Column(Date)
    instagram = Column(String(100))
    restricciones = Column(Text)
    
    # Datos del dueño
    nombre_dueno = Column(String(100), nullable=False)
    telefono_dueno = Column(String(20))
    direccion_dueno = Column(String(200))
    email_dueno = Column(String(100))
    
    # Datos para guardería
    dias_semana = Column(String(100))
    dias_totales = Column(Integer)
    sector = Column(String(100))
    valor_dia = Column(Float)
    abono1 = Column(Float)
    fecha_abono1 = Column(Date)
    abono2 = Column(Float)
    fecha_abono2 = Column(Date)
    vacuna = Column(Boolean, default=False)
    fecha_vacuna = Column(Date)
    saldo = Column(Float, default=0)
    activo = Column(Boolean, default=True)
    fecha_registro = Column(Date, default=datetime.utcnow)
    ultima_asistencia = Column(Date)
    
    # Notas generales
    notas_adicionales = Column(Text)
    
    # Tipo de servicio (para diferenciar si es mascota regular, de guardería o ambos)
    tipo_servicio = Column(String(50))  # 'regular', 'guarderia', 'ambos'
    
    # Relaciones
    reservas = relationship("Reserva", back_populates="mascota")
    asistencias_guarderia = relationship("AsistenciaGuarderia", back_populates="mascota")
    pagos_guarderia = relationship("PagoGuarderia", back_populates="mascota")
    estancias_hotel = relationship("EstanciaHotel", back_populates="mascota")  # Cambiado a back_populates
    dias_sol = relationship("DiaSol", back_populates="mascota")  # Cambiado a back_populates

class Servicio(db.Model):
    __tablename__ = 'servicios'

    id = Column(Integer, primary_key=True)
    nombre = Column(String(100), nullable=False)
    descripcion = Column(Text)
    precio = Column(Float, nullable=False)

    reservas = relationship("Reserva", back_populates="servicio")

class Reserva(db.Model):
    __tablename__ = 'reservas'

    id = Column(Integer, primary_key=True)
    mascota_id = Column(Integer, ForeignKey('mascotas.id'), nullable=False)
    servicio_id = Column(Integer, ForeignKey('servicios.id'), nullable=False)
    fecha_inicio = Column(Date, nullable=False)
    fecha_fin = Column(Date)
    hora = Column(Time)
    estado = Column(Enum('pendiente', 'en_progreso', 'completada', 'cancelada', name='estado_reserva'), default='pendiente')

    mascota = relationship("Mascota", back_populates="reservas")
    servicio = relationship("Servicio", back_populates="reservas")
    factura = relationship("Factura", back_populates="reserva", uselist=False)

class Factura(db.Model):
    __tablename__ = 'facturas'

    id = Column(Integer, primary_key=True)
    reserva_id = Column(Integer, ForeignKey('reservas.id'), nullable=False)
    fecha_emision = Column(Date, nullable=False)
    monto_total = Column(Float, nullable=False)
    estado = Column(Enum('pendiente', 'pagada', 'anulada', name='estado_factura'), default='pendiente')

    reserva = relationship("Reserva", back_populates="factura")
    pagos = relationship("Pago", back_populates="factura")

class Pago(db.Model):
    __tablename__ = 'pagos'

    id = Column(Integer, primary_key=True)
    factura_id = Column(Integer, ForeignKey('facturas.id'), nullable=False)
    fecha_pago = Column(Date, nullable=False)
    monto = Column(Float, nullable=False)
    metodo_pago = Column(String(50))

    factura = relationship("Factura", back_populates="pagos")

class Ruta(db.Model):
    __tablename__ = 'rutas'

    id = Column(Integer, primary_key=True)
    nombre = Column(String(100), nullable=False)
    descripcion = Column(Text)
    fecha = Column(Date, nullable=False)
    hora_inicio = Column(Time, nullable=False)
    hora_fin = Column(Time)
    completada = Column(Boolean, default=False)
    hora_recogida = Column(Time, nullable=False)
    direccion_recogida = Column(String(200), nullable=False)
    notificacion_enviada = Column(Boolean, default=False)
    conductor = Column(String(100))
    estado = Column(Enum('pendiente', 'en_progreso', 'completada', name='estado_ruta'), default='pendiente')

    paradas = relationship("ParadaRuta", back_populates="ruta")

class ParadaRuta(db.Model):
    __tablename__ = 'paradas_ruta'

    id = Column(Integer, primary_key=True)
    ruta_id = Column(Integer, ForeignKey('rutas.id'), nullable=False)
    mascota_id = Column(Integer, ForeignKey('mascotas.id'), nullable=False)
    orden = Column(Integer, nullable=False)
    completada = Column(Boolean, default=False)

    ruta = relationship("Ruta", back_populates="paradas")
    mascota = relationship("Mascota")

class Ingreso(db.Model):
    __tablename__ = 'ingresos'

    id = Column(Integer, primary_key=True)
    fecha = Column(Date, nullable=False)
    descripcion = Column(String(200))
    monto = Column(Float, nullable=False)
    factura_id = Column(Integer, ForeignKey('facturas.id'))

    factura = relationship("Factura")

class Egreso(db.Model):
    __tablename__ = 'egresos'

    id = Column(Integer, primary_key=True)
    fecha = Column(Date, nullable=False)
    descripcion = Column(String(200))
    monto = Column(Float, nullable=False)
    categoria = Column(String(100))

class ComprobanteDiario(db.Model):
    __tablename__ = 'comprobantes_diarios'

    id = Column(Integer, primary_key=True)
    fecha = Column(Date, nullable=False)
    descripcion = Column(Text)
    total_ingresos = Column(Float, default=0)
    total_egresos = Column(Float, default=0)
    saldo = Column(Float, default=0)

class Usuario(db.Model):
    __tablename__ = 'usuarios'
    id = Column(Integer, primary_key=True)
    nombre = Column(String(50), nullable=False)
    apellido = Column(String(50), nullable=False)
    identificacion = Column(String(20), unique=True, nullable=False)
    email = Column(String(100), unique=True, nullable=False)
    password = Column(String(255), nullable=False)
    fecha_registro = Column(Date, default=func.now())

class EstanciaHotel(db.Model):
    __tablename__ = 'estancias_hotel'

    id = Column(Integer, primary_key=True)
    mascota_id = Column(Integer, ForeignKey('mascotas.id'), nullable=False)
    fecha_ingreso = Column(Date, nullable=False)
    fecha_salida = Column(Date, nullable=False)
    noches = Column(Integer)
    valor_dia = Column(Float, nullable=False)
    transporte = Column(Float, default=0)
    vacuna = Column(Float, default=0)
    bano = Column(Float, default=0)
    cuido = Column(Float, default=0)
    total = Column(Float)
    saldo = Column(Float)
    observaciones = Column(Text)
    
    mascota = relationship("Mascota", back_populates="estancias_hotel")  # Cambiado para coincidir
    abonos = relationship("AbonoHotel", back_populates="estancia") 

class DiaSol(db.Model):
    __tablename__ = 'dias_sol'

    id = Column(Integer, primary_key=True)
    mascota_id = Column(Integer, ForeignKey('mascotas.id'), nullable=False)
    fecha = Column(Date, nullable=False)
    servicio = Column(String(100), nullable=False)
    transporte = Column(Boolean, default=False)
    valor_servicio = Column(Float, nullable=False)
    valor_transporte = Column(Float, default=0)
    pago = Column(Float, default=0)
    saldo = Column(Float, default=0)
    observaciones = Column(Text)
    estado = Column(Enum('pendiente', 'completado', 'cancelado', name='estado_diasol'), default='pendiente')
    fecha_creacion = Column(DateTime, default=func.now())
    
    # Relaciones
    mascota = relationship("Mascota", back_populates="dias_sol")  # Cambiado a back_populates
    # Cambiamos esta línea para evitar el conflicto de backref
    pagos = relationship("DiaSolPago", back_populates="dia_sol", cascade="all, delete-orphan")

class DiaSolPago(db.Model):
    __tablename__ = 'diasol_pagos'

    id = Column(Integer, primary_key=True)
    dia_sol_id = Column(Integer, ForeignKey('dias_sol.id'), nullable=False)
    fecha = Column(Date, nullable=False)
    monto = Column(Float, nullable=False)
    numero_pago = Column(Integer, nullable=False)
    
    # Cambiamos backref por back_populates
    dia_sol = relationship("DiaSol", back_populates="pagos")


class AsistenciaGuarderia(db.Model):
    __tablename__ = 'asistencia_guarderia'
    
    id = Column(Integer, primary_key=True)
    mascota_id = Column(Integer, ForeignKey('mascotas.id'), nullable=False)
    fecha = Column(Date, nullable=False)
    asistio = Column(Boolean, default=True)
    hora_entrada = Column(Time)
    hora_salida = Column(Time)
    recogida = Column(Boolean, default=False)
    entrega = Column(Boolean, default=False)
    observaciones_dia = Column(Text)
    created_at = Column(DateTime, default=func.now())
    
    mascota = relationship("Mascota", back_populates="asistencias_guarderia")

class FacturaGuarderia(db.Model):
    __tablename__ = 'facturas_guarderia'
    
    id = Column(Integer, primary_key=True)
    mascota_id = Column(Integer, ForeignKey('mascotas.id'), nullable=False)
    fecha_emision = Column(Date, nullable=False)
    periodo_inicio = Column(Date)
    periodo_fin = Column(Date)
    valor_mensual = Column(Float, nullable=False)
    valor_transporte = Column(Float, default=0)
    valor_adicionales = Column(Float, default=0)
    monto_total = Column(Float, nullable=False)
    saldo_pendiente = Column(Float, nullable=False)
    estado = Column(Enum('pendiente', 'pagada', 'anulada', name='estado_factura_guarderia'), default='pendiente')
    observaciones = Column(Text)
    created_at = Column(DateTime, default=func.now())
    
    mascota = relationship("Mascota")
    pagos = relationship("PagoGuarderia", back_populates="factura")

class PagoGuarderia(db.Model):
    __tablename__ = 'pagos_guarderia'
    
    id = Column(Integer, primary_key=True)
    mascota_id = Column(Integer, ForeignKey('mascotas.id'), nullable=False)
    factura_id = Column(Integer, ForeignKey('facturas_guarderia.id'))  # Nuevo campo
    fecha_pago = Column(Date, nullable=False)
    monto = Column(Float, nullable=False)
    tipo_pago = Column(String(50))  # Abono1, Abono2, Mensualidad, etc.
    periodo_inicio = Column(Date)
    periodo_fin = Column(Date)
    comprobante = Column(String(255))
    observaciones = Column(Text)
    created_at = Column(DateTime, default=func.now())
    
    mascota = relationship("Mascota", back_populates="pagos_guarderia")
    factura = relationship("FacturaGuarderia", back_populates="pagos")  # Nueva relación

class AbonoHotel(db.Model):
    __tablename__ = 'abonos_hotel'

    id = Column(Integer, primary_key=True)
    estancia_id = Column(Integer, ForeignKey('estancias_hotel.id'), nullable=False)
    fecha = Column(Date, nullable=False)
    monto = Column(Float, nullable=False)
    numero_abono = Column(Integer, nullable=False)  # Para identificar si es abono 1, 2, etc.

    estancia = relationship("EstanciaHotel", back_populates="abonos")  # Cambiado a back_populates