"""
images_service.py

Purpose:
  Encapsulate image discovery and grouping logic. Responsible for scanning
  `static/User-photos/`, merging DB hints (file_paths), and grouping images for
  the gallery views.

Exports:
  - collect_user_images(user_id, db, static_path) -> list[dict]
  - latest_from_db_or_fs(cam_id, file_paths, static_path) -> (datetime|None, rel|None)
  - group_images_by_time(items) -> list[section]
"""

import os
from datetime import datetime
from .helpers import parse_ts_from_any, build_media_url


def collect_user_images(user_id: int, db, static_path: str):
    images_by_rel = {}
    # Build set of the user's camera ids
    cam_rows = db.execute('SELECT camera_id, file_paths FROM cameras WHERE user_id = ?', (user_id,)).fetchall()
    user_cam_ids = {str(r['camera_id']) for r in cam_rows}
    # Seed from DB file_paths when present
    for row in cam_rows:
        file_paths = row['file_paths'] or ''
        for raw in [p.strip() for p in file_paths.split(',') if p.strip()]:
            rel = _normalize_to_static_user_photos(raw)
            ts, cam = parse_ts_from_any(rel)
            abs_path = os.path.join(static_path, rel)
            if os.path.exists(abs_path):
                ts = ts or datetime.fromtimestamp(os.path.getmtime(abs_path))
                images_by_rel[rel] = {
                    'rel': rel,
                    'url': build_media_url(rel),
                    'ts': ts,
                    'camera_id': cam or str(row['camera_id'])
                }
    # Filesystem scan
    root = os.path.join(static_path, 'User-photos')
    for dirpath, _, files in os.walk(root):
        for name in files:
            if not name.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.webp')):
                continue
            ts, cam = parse_ts_from_any(name)
            if cam and cam in user_cam_ids:
                abs_path = os.path.join(dirpath, name)
                rel = os.path.relpath(abs_path, static_path).replace('\\', '/')
                if rel not in images_by_rel:
                    ts = ts or datetime.fromtimestamp(os.path.getmtime(abs_path))
                    images_by_rel[rel] = {
                        'rel': rel,
                        'url': build_media_url(rel),
                        'ts': ts,
                        'camera_id': cam
                    }
    images = list(images_by_rel.values())
    images.sort(key=lambda x: x['ts'] or datetime.min, reverse=True)
    return images


def latest_from_db_or_fs(cam_id: str, file_paths: str, static_path: str):
    latest_dt = None
    latest_rel = None
    # Prefer DB file_paths
    if file_paths:
        for raw in [p.strip() for p in file_paths.split(',') if p.strip()]:
            rel = _normalize_to_static_user_photos(raw)
            ts, cam = parse_ts_from_any(rel)
            abs_path = os.path.join(static_path, rel)
            if not os.path.exists(abs_path):
                continue
            candidate_dt = ts or datetime.fromtimestamp(os.path.getmtime(abs_path))
            if cam == cam_id and candidate_dt and (latest_dt is None or candidate_dt > latest_dt):
                latest_dt = candidate_dt
                latest_rel = rel
    # Scan filesystem (recursive)
    root = os.path.join(static_path, 'User-photos')
    for dirpath, _, files in os.walk(root):
        for name in files:
            if not name.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.webp')):
                continue
            ts, cam = parse_ts_from_any(name)
            if cam != cam_id:
                continue
            abs_path = os.path.join(dirpath, name)
            candidate_dt = ts or datetime.fromtimestamp(os.path.getmtime(abs_path))
            if candidate_dt and (latest_dt is None or candidate_dt > latest_dt):
                latest_dt = candidate_dt
                rel = os.path.relpath(abs_path, static_path).replace('\\', '/')
                latest_rel = rel
    return latest_dt, latest_rel


def group_images_by_time(items):
    from datetime import datetime
    now = datetime.now()
    today = now.date()
    start_of_month = today.replace(day=1)
    sections = {
        'Danas': [],
        'Jučer': [],
        'Zadnjih 7 dana': [],
        'Ovaj mjesec': [],
        'Starije od mjesec dana': [],
    }
    for it in items:
        ts = it.get('ts')
        if not isinstance(ts, datetime):
            sections['Starije od mjesec dana'].append(it)
            continue
        d = ts.date()
        delta_days = (today - d).days
        if delta_days == 0:
            sections['Danas'].append(it)
        elif delta_days == 1:
            sections['Jučer'].append(it)
        elif 1 < delta_days <= 7:
            sections['Zadnjih 7 dana'].append(it)
        elif d >= start_of_month:
            sections['Ovaj mjesec'].append(it)
        else:
            sections['Starije od mjesec dana'].append(it)
    ordered = []
    for key in ['Danas', 'Jučer', 'Zadnjih 7 dana', 'Ovaj mjesec', 'Starije od mjesec dana']:
        if sections[key]:
            sections[key].sort(key=lambda x: x.get('ts') or datetime.min, reverse=True)
            ordered.append({'title': key, 'items': sections[key]})
    return ordered


def _normalize_to_static_user_photos(p: str) -> str:
    p = p.replace('\\', '/').lstrip('/')
    if p.startswith('static/'):
        p = p[len('static/') : ]
    if 'User-photos/' in p:
        p = p[p.find('User-photos/') : ]
    elif '/' not in p:
        p = f'User-photos/{p}'
    return p


