"""
Discord 웹훅 알림 (단방향 push).

URL 1개로 끝. 봇 등록·서버 운영 0. 실패 시 silent (앱 동작 안 막음).
"""
from __future__ import annotations
import json
import re
import urllib.request
import urllib.error
from datetime import datetime
from typing import Optional, List

# Discord/Cloudflare는 Python 기본 UA(Python-urllib/3.x)를 봇으로 차단(error 1010).
# 일반 브라우저 UA로 위장해야 통과.
# 버전은 core/version.py에서 동기화.
from core.version import __version__
USER_AGENT = f'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ClockOutCalculator/{__version__}'

# Discord embed 색상 (decimal)
COLOR_GREEN = 0x57F287
COLOR_BLUE = 0x5865F2
COLOR_YELLOW = 0xFEE75C
COLOR_PINK = 0xEB459E
COLOR_ORANGE = 0xED4245

# Discord 웹훅 URL 패턴: https://(discord.com|discordapp.com|...)/api/webhooks/{ID:digits}/{TOKEN}
# canary./ptb. 서브도메인도 허용. PTB 모바일 앱이 종종 그 URL 발급.
_WEBHOOK_RE = re.compile(
    r'^https://(?:(?:canary|ptb)\.)?discord(?:app)?\.com/api/webhooks/\d{17,20}/[\w-]{50,}$'
)


def is_valid_webhook_url(url: str) -> bool:
    """입력된 URL이 Discord webhook 형식인지 검증.

    형식만 확인 — 실제 도달성·토큰 유효성은 send_test()로 검증해야 함.
    빈 문자열이나 공백은 False (비활성 상태로 간주).
    """
    if not url or not isinstance(url, str):
        return False
    return bool(_WEBHOOK_RE.match(url.strip()))


def send(webhook_url: str, title: str, description: str,
         color: int = COLOR_BLUE, fields: Optional[List[dict]] = None,
         timeout: int = 5) -> bool:
    """Discord 웹훅으로 embed 메시지 발송.

    Args:
        webhook_url: Discord webhook URL (https://discord.com/api/webhooks/{ID}/{TOKEN})
        title, description: embed 본문
        color: embed 좌측 색상 바 (10진수, 0xRRGGBB)
        fields: [{"name": "필드명", "value": "값", "inline": True}, ...]
        timeout: 요청 타임아웃(초)

    Returns:
        성공 시 True. URL 비었거나 네트워크/4xx/5xx 시 False.
    """
    if not is_valid_webhook_url(webhook_url):
        return False

    payload = {
        "embeds": [{
            "title": title,
            "description": description,
            "color": color,
            "fields": fields or [],
            "timestamp": datetime.utcnow().isoformat(),
            "footer": {"text": "Clock-out Time Calculator"},
        }]
    }
    data = json.dumps(payload, ensure_ascii=False).encode('utf-8')
    req = urllib.request.Request(
        webhook_url, data=data,
        headers={
            'Content-Type': 'application/json; charset=utf-8',
            'User-Agent': USER_AGENT,
        },
        method='POST',
    )
    try:
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            return 200 <= resp.status < 300
    except (urllib.error.URLError, urllib.error.HTTPError, OSError, TimeoutError):
        return False


def send_test(webhook_url: str) -> bool:
    """온보딩/설정에서 호출하는 테스트 메시지."""
    return send(
        webhook_url,
        title="🔔 테스트 알림",
        description="Clock-out Time Calculator의 Discord 연동이 정상 작동합니다.",
        color=COLOR_GREEN,
    )


def send_clock_in(webhook_url: str, time_str: str) -> bool:
    return send(
        webhook_url,
        title="🟢 출근",
        description=f"오늘 {time_str}에 출근 기록되었습니다.",
        color=COLOR_GREEN,
    )


def send_clock_out(webhook_url: str, time_str: str, total_hours: float,
                   overtime_minutes: int, overtime_earned: int) -> bool:
    fields = [
        {"name": "총 근무시간", "value": f"{total_hours:.1f}시간", "inline": True},
    ]
    if overtime_minutes > 0:
        fields.append({
            "name": "연장근무",
            "value": f"{overtime_minutes}분 → {overtime_earned}분 적립",
            "inline": True,
        })
    color = COLOR_YELLOW if overtime_minutes > 0 else COLOR_BLUE
    return send(
        webhook_url,
        title="✅ 퇴근",
        description=f"오늘 {time_str}에 퇴근 처리되었습니다.",
        color=color,
        fields=fields,
    )


def send_health_warning(webhook_url: str, hours_continuous: float) -> bool:
    return send(
        webhook_url,
        title="🌿 휴식 권고",
        description=f"{hours_continuous:.1f}시간 연속 근무 중입니다.\n잠시 일어나서 스트레칭하세요.",
        color=COLOR_PINK,
    )
