"""
map_routes.py

Purpose:
  Map and marker endpoints used by the Leaflet-based map UI. Provides logic for
  camera locations and generic fauna/structure markers. Performs schema
  migrations-on-boot for required columns/tables.

Routes:
  - GET /karta
  - GET /get_available_cameras
  - POST /add_camera_marker
  - POST /add_item_marker
  - GET /get_marker_locations
  - POST /delete_marker
"""

import sqlite3
from flask import Blueprint, render_template, jsonify, request, session
from .security import login_required
from .db import get_db
from .security_enhancements import validate_geographic_coordinates


bp = Blueprint('map_routes', __name__)


def _ensure_map_schema(db):
    cols = [row[1] for row in db.execute('PRAGMA table_info(cameras)').fetchall()]
    if 'added_to_map' not in cols:
        try:
            db.execute('ALTER TABLE cameras ADD COLUMN added_to_map INTEGER DEFAULT 0')
        except sqlite3.Error:
            pass
    if 'location' not in cols:
        try:
            db.execute('ALTER TABLE cameras ADD COLUMN location TEXT')
        except sqlite3.Error:
            pass
    db.execute(
        'CREATE TABLE IF NOT EXISTS markers ('
        ' id INTEGER PRIMARY KEY AUTOINCREMENT,'
        ' user_id INTEGER NOT NULL,'
        ' type TEXT NOT NULL,'
        ' latitude REAL NOT NULL,'
        ' longitude REAL NOT NULL,'
        ' name TEXT)'
    )
    db.commit()


@bp.route('/karta')
@login_required
def map_page():
    return render_template('map.html')


@bp.route('/get_available_cameras')
@login_required
def get_available_cameras():
    db = get_db()
    _ensure_map_schema(db)
    cur = db.execute(
        'SELECT camera_id, camera_name, IFNULL(added_to_map, 0) AS added_to_map'
        ' FROM cameras WHERE user_id=? AND IFNULL(added_to_map, 0)=0'
        ' ORDER BY camera_name COLLATE NOCASE',
        (session['user_id'],)
    )
    data = [{'camera_id': row['camera_id'], 'name': row['camera_name'], 'added_to_map': row['added_to_map']} for row in cur.fetchall()]
    return jsonify(data)


@bp.route('/add_camera_marker', methods=['POST'])
@login_required
def add_camera_marker():
    lat = request.form.get('lat') or request.json.get('lat') if request.is_json else None
    lng = request.form.get('lng') or request.json.get('lng') if request.is_json else None
    camera_id = (request.form.get('camera_id') or (request.json.get('camera_id') if request.is_json else '')).strip()
    if not lat or not lng or not camera_id:
        return jsonify({'success': False, 'message': 'Nedostaju podaci.'}), 400
    
    # Use secure coordinate validation
    valid, error_msg, coordinates = validate_geographic_coordinates(lat, lng)
    if not valid:
        return jsonify({'success': False, 'message': error_msg}), 400
    lat_f, lng_f = coordinates
    db = get_db()
    _ensure_map_schema(db)
    # Verify camera ownership
    row = db.execute('SELECT camera_name FROM cameras WHERE user_id=? AND camera_id=?', (session['user_id'], camera_id)).fetchone()
    if not row:
        return jsonify({'success': False, 'message': 'Kamera nije pronađena.'}), 404
    location = f"{lat_f},{lng_f}"
    try:
        db.execute('UPDATE cameras SET location=?, added_to_map=1 WHERE user_id=? AND camera_id=?', (location, session['user_id'], camera_id))
        db.commit()
        return jsonify({'success': True, 'camera_name': row['camera_name'], 'camera_id': camera_id})
    except sqlite3.Error:
        return jsonify({'success': False, 'message': 'Greška baze.'}), 500


@bp.route('/add_item_marker', methods=['POST'])
@login_required
def add_item_marker():
    lat = request.form.get('lat') or request.json.get('lat') if request.is_json else None
    lng = request.form.get('lng') or request.json.get('lng') if request.is_json else None
    item_type = (request.form.get('item_type') or (request.json.get('item_type') if request.is_json else '')).strip()
    item_name = (request.form.get('item_name') or (request.json.get('item_name') if request.is_json else '')).strip()
    if not item_name:
        item_name = item_type
    if not lat or not lng or not item_type:
        return jsonify({'success': False, 'message': 'Nedostaju podaci.'}), 400
    
    # Use secure coordinate validation
    valid, error_msg, coordinates = validate_geographic_coordinates(lat, lng)
    if not valid:
        return jsonify({'success': False, 'message': error_msg}), 400
    lat_f, lng_f = coordinates
    db = get_db()
    _ensure_map_schema(db)
    try:
        cur = db.execute('INSERT INTO markers (user_id, type, latitude, longitude, name) VALUES (?, ?, ?, ?, ?)', (session['user_id'], item_type, lat_f, lng_f, item_name))
        db.commit()
        return jsonify({'success': True, 'item_name': item_name, 'item_id': cur.lastrowid})
    except sqlite3.Error:
        return jsonify({'success': False, 'message': 'Greška baze.'}), 500


@bp.route('/get_marker_locations')
@login_required
def get_marker_locations():
    db = get_db()
    _ensure_map_schema(db)
    result = []
    # Generic markers
    for m in db.execute('SELECT id, type, latitude, longitude, name FROM markers WHERE user_id=?', (session['user_id'],)).fetchall():
        result.append({
            'id': m['id'],
            'type': m['type'],
            'latitude': m['latitude'],
            'longitude': m['longitude'],
            'name': m['name'] or m['type']
        })
    # Camera markers stored in cameras table
    for c in db.execute('SELECT camera_id, camera_name, location FROM cameras WHERE user_id=? AND IFNULL(added_to_map,0)=1 AND IFNULL(location,"")<>""', (session['user_id'],)).fetchall():
        try:
            lat_s, lng_s = (c['location'] or '').split(',')
            lat_f = float(lat_s); lng_f = float(lng_s)
        except Exception:
            continue
        result.append({
            'id': str(c['camera_id']),
            'type': 'camera',
            'latitude': lat_f,
            'longitude': lng_f,
            'name': c['camera_name']
        })
    return jsonify(result)


@bp.route('/delete_marker', methods=['POST'])
@login_required
def delete_marker():
    item_id = (request.form.get('item_id') or (request.json.get('item_id') if request.is_json else '')).strip()
    item_type = (request.form.get('item_type') or (request.json.get('item_type') if request.is_json else '')).strip()
    if not item_id:
        return jsonify({'success': False, 'message': 'Nedostaju podaci.'}), 400
    db = get_db()
    _ensure_map_schema(db)
    try:
        if item_type == 'camera':
            db.execute('UPDATE cameras SET location=NULL, added_to_map=0 WHERE user_id=? AND camera_id=?', (session['user_id'], item_id))
            db.commit()
            return jsonify({'success': True})
        else:
            db.execute('DELETE FROM markers WHERE id=? AND user_id=?', (item_id, session['user_id']))
            db.commit()
            return jsonify({'success': True})
    except sqlite3.Error:
        return jsonify({'success': False, 'message': 'Greška baze.'}), 500


