from __future__ import annotations

import time
from datetime import datetime, timezone

from app.db import execute, get_int, query_all, query_one, utcnow
from .log_service import error


class FollowService:
    def check(self, client, user_id: str, username: str = '') -> str:
        cache_seconds = max(30, get_int('follow_cache_duration', 600))
        cached = query_one(
            "SELECT * FROM follow_checks WHERE instagram_user_id=? AND datetime(checked_at) >= datetime('now', ?) ORDER BY id DESC LIMIT 1",
            (str(user_id), f'-{cache_seconds} seconds'),
        )
        if cached:
            self._record(user_id, username, cached['result'], 'cache', 0, None)
            return cached['result']

        max_checks = max(1, get_int('max_follow_checks', 3))
        window = max(60, get_int('follow_check_window', 600))
        recent = query_one(
            "SELECT COUNT(*) AS c FROM follow_checks WHERE instagram_user_id=? AND source='instagram' AND datetime(checked_at) >= datetime('now', ?)",
            (str(user_id), f'-{window} seconds'),
        )
        if recent and recent['c'] >= max_checks:
            return 'unknown'

        started = time.monotonic()
        try:
            relation = client.user_friendship_v1(str(user_id))
            followed_by = getattr(relation, 'followed_by', None)
            if followed_by is True:
                result = 'followed'
            elif followed_by is False:
                result = 'not_followed'
            else:
                result = 'unknown'
            self._record(user_id, username, result, 'instagram', int((time.monotonic() - started) * 1000), None)
            return result
        except Exception as exc:
            error(exc, 'FollowService', 'check', user_id=str(user_id), error_type='FOLLOW_CHECK_ERROR')
            self._record(user_id, username, 'unknown', 'instagram', int((time.monotonic() - started) * 1000), str(exc))
            return 'unknown'

    def _record(self, user_id, username, result, source, duration, err):
        execute(
            'INSERT INTO follow_checks(instagram_user_id, username, result, source, duration_ms, error, checked_at) VALUES (?, ?, ?, ?, ?, ?, ?)',
            (str(user_id), username, result, source, duration, err, utcnow()),
        )
