from uuid import uuid4
import os
from sqlalchemy.orm import joinedload

from flask import (
    Blueprint,
    render_template,
    redirect,
    url_for,
    request,
    flash,
    current_app,
)
from flask_login import login_required, current_user

from app import db
from .models import Plant, PlantCommonName, PlantScientificName
from .forms import PlantForm
from plugins.media.models import Media
from plugins.media.routes import (
    save_media_file,
    delete_media_file,
    rotate_media_file,
    generate_image_url,
)


bp = Blueprint(
    'plant',
    __name__,
    url_prefix='/plants',
    template_folder='templates',
)

@bp.app_context_processor
def inject_image_helper():
    return dict(generate_image_url=generate_image_url)

@bp.route('/', methods=['GET'])
@login_required
def index():
    plants = (
        Plant.query
        .options(joinedload(Plant.media_items))
        .filter_by(owner_id=current_user.id)
        .order_by(Plant.id.desc())
        .all()
    )

    user_plants_count  = Plant.query.filter_by(owner_id=current_user.id).count()
    user_images_count  = Media.query.filter_by(uploader_id=current_user.id).count()
    total_plants_count = Plant.query.count()
    total_images_count = Media.query.count()

    plant_types = [
        pt[0]
        for pt in (
            db.session.query(Plant.plant_type)
            .filter_by(owner_id=current_user.id)
            .distinct()
            .all()
        )
    ]

    stats = {
        'user_plants':  user_plants_count,
        'user_images':  user_images_count,
        'total_plants': total_plants_count,
        'total_images': total_images_count,
    }

    return render_template(
        'plant/index.html',
        plants=plants,
        plant_types=plant_types,
        stats=stats,
    )

@bp.route('/create', methods=['GET', 'POST'])
@login_required
def create():
    form = PlantForm()

    form.plant_type.choices = [
        ('plant', 'Plant'),
        ('cutting', 'Cutting'),
        ('seed', 'Seed'),
        ('tissue_culture', 'Tissue Culture'),
        ('division', 'Division'),
    ]
    form.common_name.choices = [
        (c.id, c.name)
        for c in PlantCommonName.query.order_by(PlantCommonName.name).all()
    ]
    form.scientific_name.choices = [
        (s.id, s.name)
        for s in PlantScientificName.query.order_by(PlantScientificName.name).all()
    ]
    form.mother_uuid.choices = [('N/A', 'None')] + [
        (
            p.uuid,
            f"{p.common_name.name if p.common_name else 'Unnamed'} – {p.uuid}"
        )
        for p in Plant.query.order_by(Plant.created_at.desc()).all()
    ]

    if form.validate_on_submit():
        new_plant = Plant(
            uuid=str(uuid4()),
            owner_id=current_user.id,
            plant_type=form.plant_type.data,
            common_id=form.common_name.data,
            scientific_id=form.scientific_name.data,
            mother_uuid=(
                form.mother_uuid.data
                if form.mother_uuid.data != 'N/A'
                else None
            ),
            custom_slug=(form.custom_slug.data.strip() or None),
            vendor_name=(form.vendor_name.data.strip() or None),
            price=(form.price.data or None),
            notes=form.notes.data,
            data_verified=form.data_verified.data,
            is_active=form.is_active.data,
        )
        db.session.add(new_plant)
        db.session.commit()
        flash('New plant created successfully.', 'success')
        return redirect(url_for('plant.edit', uuid_val=new_plant.uuid))

    return render_template('plant/create.html', form=form)

@bp.route('/<uuid:uuid_val>', methods=['GET'])
@login_required
def detail(uuid_val):
    plant = Plant.query.filter_by(
        uuid=str(uuid_val),
        owner_id=current_user.id,
    ).first_or_404()
    return render_template('plant/detail.html', plant=plant)

@bp.route('/<uuid:uuid_val>/edit', methods=['GET', 'POST'])
@login_required
def edit(uuid_val):
    plant = Plant.query.filter_by(
        uuid=str(uuid_val),
        owner_id=current_user.id,
    ).first_or_404()

    form = PlantForm()

    form.plant_type.choices = [
        ('plant', 'Plant'),
        ('cutting', 'Cutting'),
        ('seed', 'Seed'),
        ('tissue_culture', 'Tissue Culture'),
        ('division', 'Division'),
    ]
    form.common_name.choices = [
        (c.id, c.name)
        for c in PlantCommonName.query.order_by(PlantCommonName.name).all()
    ]
    form.scientific_name.choices = [
        (s.id, s.name)
        for s in PlantScientificName.query.order_by(PlantScientificName.name).all()
    ]
    form.mother_uuid.choices = [('N/A', 'None')] + [
        (
            p.uuid,
            f"{p.common_name.name if p.common_name else 'Unnamed'} – {p.uuid}"
        )
        for p in Plant.query.filter(Plant.uuid != plant.uuid).all()
    ]

    if request.method == 'GET':
        form.plant_type.data      = plant.plant_type
        form.common_name.data     = plant.common_id
        form.scientific_name.data = plant.scientific_id
        form.mother_uuid.data     = plant.mother_uuid or 'N/A'
        form.custom_slug.data     = plant.custom_slug or ''
        form.vendor_name.data     = plant.vendor_name or ''
        form.price.data           = plant.price or None
        form.notes.data           = plant.notes
        form.data_verified.data   = plant.data_verified
        form.is_active.data       = getattr(plant, 'is_active', True)

    if form.validate_on_submit():
        plant.plant_type    = form.plant_type.data
        plant.common_id     = form.common_name.data
        plant.scientific_id = form.scientific_name.data
        plant.mother_uuid   = (
            form.mother_uuid.data
            if form.mother_uuid.data != 'N/A'
            else None
        )
        plant.custom_slug   = (form.custom_slug.data.strip() or None)
        plant.vendor_name   = (form.vendor_name.data.strip() or None)
        plant.price         = (form.price.data or None)
        plant.notes         = form.notes.data
        plant.data_verified = form.data_verified.data
        plant.is_active     = form.is_active.data

        # — patch to save whichever radio was checked —
        featured_id = request.form.get("featured_media_id")
        if featured_id and featured_id.isdigit():
            plant.featured_media_id = int(featured_id)

        db.session.commit()
        flash('Plant updated successfully.', 'success')
        return redirect(url_for('plant.detail', uuid_val=plant.uuid))

    return render_template('plant/edit.html', form=form, plant=plant)

@bp.route('/<uuid:uuid_val>/upload', methods=['POST'])
@login_required
def upload_image(uuid_val):
    plant = Plant.query.filter_by(uuid=str(uuid_val)).first_or_404()
    file  = request.files.get('file')
    if file and file.filename:
        save_media_file(
            file,
            current_user.id,
            related_model='plant',
            related_uuid=str(plant.uuid),
        )
        flash('Image uploaded successfully.', 'success')
    return redirect(url_for('plant.edit', uuid_val=plant.uuid))

@bp.route("/feature/<int:media_id>", methods=["POST"])
@login_required
def set_featured_image(media_id):
    media = Media.query.get_or_404(media_id)
    if current_user.id != media.uploader_id and current_user.role != "admin":
        return jsonify({"error": "Not authorized"}), 403

    plant = media.plant
    plant.featured_media_id = media.id
    db.session.commit()
    return jsonify({"status": "success", "media_id": media.id})

@bp.route('/<uuid:uuid_val>/delete/<int:media_id>', methods=['POST'])
@login_required
def delete_image(uuid_val, media_id):
    plant = Plant.query.filter_by(uuid=str(uuid_val)).first_or_404()
    media = Media.query.get_or_404(media_id)
    delete_media_file(media)
    flash('Image deleted.', 'success')
    return redirect(url_for('plant.edit', uuid_val=plant.uuid))

@bp.route('/<uuid:uuid_val>/rotate/<int:media_id>', methods=['POST'])
@login_required
def rotate_image(uuid_val, media_id):
    plant = Plant.query.filter_by(uuid=str(uuid_val)).first_or_404()
    media = Media.query.get_or_404(media_id)
    rotate_media_file(media)
    flash('Image rotated.', 'success')
    return redirect(url_for('plant.edit', uuid_val=plant.uuid))
