import uuid
from datetime import datetime
from app.extensions import db


class AnalysisType(db.Model):
    __tablename__ = 'analysis_types'

    id = db.Column(db.Integer, primary_key=True)
    slug = db.Column(db.String(50), unique=True, nullable=False)
    name = db.Column(db.String(255), nullable=False)
    description = db.Column(db.Text)
    category = db.Column(db.String(50))  # home_range, movement, habitat, metric

    # Eligibility criteria
    min_fixes = db.Column(db.Integer, default=0)
    min_animals = db.Column(db.Integer, default=1)
    min_duration_hours = db.Column(db.Float, default=0)
    requires_regular_sampling = db.Column(db.Boolean, default=False)

    # Python callable reference
    python_module = db.Column(db.String(255), nullable=False)
    python_function = db.Column(db.String(255), nullable=False)
    default_params = db.Column(db.JSON, default=dict)

    runs = db.relationship('AnalysisRun', backref='analysis_type', lazy='dynamic')


class AnalysisRun(db.Model):
    __tablename__ = 'analysis_runs'

    id = db.Column(db.Integer, primary_key=True)
    uuid = db.Column(db.String(36), default=lambda: str(uuid.uuid4()), unique=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    dataset_id = db.Column(db.Integer, db.ForeignKey('datasets.id'))
    analysis_type_id = db.Column(db.Integer, db.ForeignKey('analysis_types.id'))

    # Subset definition
    animal_ids = db.Column(db.JSON)  # list of animal_id strings
    time_start = db.Column(db.DateTime)
    time_end = db.Column(db.DateTime)
    bbox = db.Column(db.JSON)  # {"min_lat":..., "max_lat":..., "min_lon":..., "max_lon":...}

    # Execution
    params = db.Column(db.JSON, default=dict)
    status = db.Column(db.String(20), default='queued')
    celery_task_id = db.Column(db.String(255))
    started_at = db.Column(db.DateTime)
    completed_at = db.Column(db.DateTime)
    error_message = db.Column(db.Text)

    # Results
    result_summary = db.Column(db.JSON)
    result_artifacts = db.Column(db.JSON)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
