# File: plugins/plant/growlog/routes.py

from uuid import UUID as _UUID
from flask import (
    Blueprint, render_template, abort, redirect,
    url_for, request, flash
)
from flask_login import login_required, current_user
from app import db
from .models import GrowLog
from .forms import GrowLogForm
from plugins.plant.models import Plant, PlantCommonName

bp = Blueprint(
    'growlog',
    __name__,
    url_prefix='/growlogs',
    template_folder='templates',
)


def _get_plant_by_uuid(uuid_val):
    """
    Normalize & validate a UUID (may be a uuid.UUID or a string),
    then return the Plant owned by current_user or 404.
    """
    # 1) If Flask gave us a real UUID, stringify it
    if isinstance(uuid_val, _UUID):
        val = str(uuid_val)
    else:
        # 2) Otherwise try to parse it
        try:
            val = str(_UUID(uuid_val))
        except (ValueError, TypeError):
            abort(404)

    # 3) Only return plants owned by this user
    return (
        Plant.query
             .filter_by(uuid=val, owner_id=current_user.id)
             .first_or_404()
    )


def _user_plant_choices():
    """
    Return [(uuid, "Common Name – uuid"), ...] for all plants
    owned by current_user, sorted by common name.
    """
    plants = (
        Plant.query
             .filter_by(owner_id=current_user.id)
             .join(PlantCommonName, Plant.common_id == PlantCommonName.id)
             .order_by(PlantCommonName.name)
             .all()
    )
    return [
        (p.uuid, f"{p.common_name.name} – {p.uuid}")
        for p in plants
    ]


@bp.route('/add', methods=['GET','POST'])
@bp.route('/<uuid:plant_uuid>/add', methods=['GET','POST'])
@login_required
def add_log(plant_uuid=None):
    form = GrowLogForm()
    # always populate the select behind the scenes
    form.plant_uuid.choices = _user_plant_choices()

    plant = None
    hide_select = False

    # if URL gave us a plant_uuid, lock to that one
    if plant_uuid:
        plant = _get_plant_by_uuid(plant_uuid)
        form.plant_uuid.data = str(plant_uuid)
        hide_select = True

    if form.validate_on_submit():
        plant = _get_plant_by_uuid(form.plant_uuid.data)
        log = GrowLog(
            plant_id   = plant.id,
            event_type = form.event_type.data,
            title      = form.title.data,
            notes      = form.notes.data,
            is_public  = form.is_public.data,
        )
        db.session.add(log)
        db.session.commit()
        flash('Grow log added.', 'success')
        return redirect(
            url_for('growlog.list_logs', plant_uuid=plant.uuid)
        )

    return render_template(
        'growlog/log_form.html',
        form               = form,
        plant              = plant,
        hide_plant_select  = hide_select,
    )


@bp.route('/', defaults={'plant_uuid': None})
@bp.route('/<uuid:plant_uuid>')
@login_required
def list_logs(plant_uuid):
    limit = request.args.get('limit', default=10, type=int)

    if plant_uuid:
        # logs for one plant
        plant = _get_plant_by_uuid(plant_uuid)
        query = GrowLog.query.filter_by(plant_id=plant.id)
    else:
        # logs across all of this user’s plants
        plant = None
        query = (
            GrowLog.query
                   .join(Plant, GrowLog.plant_id == Plant.id)
                   .filter(Plant.owner_id == current_user.id)
        )

    logs = (
        query
        .order_by(GrowLog.created_at.desc())
        .limit(limit)
        .all()
    )

    return render_template(
        'growlog/log_list.html',
        plant = plant,
        logs  = logs,
        limit = limit,
    )


@bp.route('/<uuid:plant_uuid>/edit/<int:log_id>', methods=['GET','POST'])
@login_required
def edit_log(plant_uuid, log_id):
    plant = _get_plant_by_uuid(plant_uuid)
    log = GrowLog.query.filter_by(id=log_id, plant_id=plant.id).first_or_404()
    form = GrowLogForm(obj=log)

    # lock the dropdown to this plant
    form.plant_uuid.choices = [(plant.uuid, plant.common_name.name)]
    form.plant_uuid.data    = plant.uuid

    if form.validate_on_submit():
        log.event_type = form.event_type.data
        log.title      = form.title.data
        log.notes      = form.notes.data
        log.is_public  = form.is_public.data
        db.session.commit()
        flash('Grow log updated.', 'success')
        return redirect(url_for('growlog.list_logs', plant_uuid=plant_uuid))

    return render_template(
        'growlog/log_form.html',
        form              = form,
        plant_uuid        = plant_uuid,
        plant             = plant,
        log               = log,
    )


@bp.route('/<uuid:plant_uuid>/delete/<int:log_id>', methods=['POST'])
@login_required
def delete_log(plant_uuid, log_id):
    plant = _get_plant_by_uuid(plant_uuid)
    log = GrowLog.query.filter_by(id=log_id, plant_id=plant.id).first_or_404()
    db.session.delete(log)
    db.session.commit()
    flash('Grow log deleted.', 'warning')
    return redirect(url_for('growlog.list_logs', plant_uuid=plant_uuid))
