"""Configuration views: config editor and LLM connectivity test."""
import traceback
import json
import time
import urllib.request
import urllib.error
import logging

from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

from config import get_config, save_config, Config

logger = logging.getLogger(__name__)


def config_view(request):
    """Config page: GET renders current config, POST saves updates."""
    cfg = get_config()

    if request.method == 'POST':
        # Build a new Config from POST data (fall back to current values)
        server = Config.Server(
            host=request.POST.get('server_host', cfg.server.host),
            port=int(request.POST.get('server_port', cfg.server.port)),
            debug=request.POST.get('server_debug') == 'true',
        )
        data = Config.Data(
            schema_strict=request.POST.get('data_schema_strict') == 'true',
            recursive=request.POST.get('data_recursive') == 'true',
        )
        clustering = Config.Clustering(
            algorithm=request.POST.get('clustering_algorithm', cfg.clustering.algorithm),
            min_cluster_size=int(request.POST.get('clustering_min_cluster_size', cfg.clustering.min_cluster_size)),
            random_state=cfg.clustering.random_state,
        )
        llm = Config.LLM(
            enabled=request.POST.get('llm_enabled') == 'true',
            base_url=request.POST.get('llm_base_url', cfg.llm.base_url),
            api_key=request.POST.get('llm_api_key', cfg.llm.api_key),
            model=request.POST.get('llm_model', cfg.llm.model),
        )
        cfg = Config(server=server, data=data, clustering=clustering, llm=llm)
        save_config(cfg)
        # Re-render with saved flag
        return render(request, 'tianxuan/config.html', {'config': cfg, 'saved': True})

    return render(request, 'tianxuan/config.html', {'config': cfg})


@csrf_exempt
def llm_test(request):
    """LLM connectivity test: POST JSON {base_url, api_key, model} → chat/completions."""
    if request.method != 'POST':
        return JsonResponse({'success': False, 'message': '仅支持 POST 请求', 'latency_ms': 0}, status=405)

    try:
        body = json.loads(request.body)
    except json.JSONDecodeError:
        return JsonResponse({'success': False, 'message': '无效的 JSON 请求体', 'latency_ms': 0})

    base_url = (body.get('base_url') or '').rstrip('/')
    api_key = body.get('api_key') or ''
    model = body.get('model') or ''

    if not base_url:
        return JsonResponse({'success': False, 'message': 'Base URL 不能为空', 'latency_ms': 0})
    if not api_key:
        return JsonResponse({'success': False, 'message': 'API Key 不能为空', 'latency_ms': 0})
    if not model:
        return JsonResponse({'success': False, 'message': 'Model 不能为空', 'latency_ms': 0})

    url = f'{base_url}/chat/completions'
    payload = json.dumps({
        'model': model,
        'messages': [{'role': 'user', 'content': 'respond with ok'}],
        'max_tokens': 5,
    }).encode('utf-8')

    req = urllib.request.Request(
        url,
        data=payload,
        headers={
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {api_key}',
        },
        method='POST',
    )

    start = time.monotonic()
    try:
        with urllib.request.urlopen(req, timeout=5) as resp:
            elapsed = int((time.monotonic() - start) * 1000)
            data = json.loads(resp.read().decode('utf-8'))
            if 'choices' in data and len(data['choices']) > 0:
                logger.info(f'[LLM_TEST] base_url={base_url} model={model} success=True latency={elapsed}ms')
                return JsonResponse({
                    'success': True,
                    'message': f'连接成功，模型 {model} 返回正常',
                    'latency_ms': elapsed,
                })
            else:
                logger.info(f'[LLM_TEST] base_url={base_url} model={model} success=True latency={elapsed}ms')
                return JsonResponse({
                    'success': True,
                    'message': f'连接成功，但响应中无 choices（原始响应已记录）',
                    'latency_ms': elapsed,
                })
    except urllib.error.HTTPError as e:
        elapsed = int((time.monotonic() - start) * 1000)
        try:
            detail = json.loads(e.read().decode('utf-8', errors='replace'))
            msg = detail.get('error', {}).get('message', str(e))
        except Exception:
            logger.error("unknown failed: {}".format(traceback.format_exc()))
            msg = str(e)
        logger.info(f'[LLM_TEST] base_url={base_url} model={model} success=False latency={elapsed}ms')
        return JsonResponse({'success': False, 'message': f'HTTP {e.code}: {msg}', 'latency_ms': elapsed})
    except urllib.error.URLError as e:
        elapsed = int((time.monotonic() - start) * 1000)
        reason = str(e.reason) if e.reason else '连接失败'
        logger.info(f'[LLM_TEST] base_url={base_url} model={model} success=False latency={elapsed}ms')
        return JsonResponse({'success': False, 'message': f'连接失败: {reason}', 'latency_ms': elapsed})
    except TimeoutError:
        elapsed = int((time.monotonic() - start) * 1000)
        logger.info(f'[LLM_TEST] base_url={base_url} model={model} success=False latency={elapsed}ms')
        return JsonResponse({'success': False, 'message': '请求超时（5秒）', 'latency_ms': elapsed})
    except Exception as e:
        elapsed = int((time.monotonic() - start) * 1000)
        logger.info(f'[LLM_TEST] base_url={base_url} model={model} success=False latency={elapsed}ms')
        return JsonResponse({'success': False, 'message': f'未知错误: {str(e)}', 'latency_ms': elapsed})
