"""
Location checkin view with evaluation_value based interaction logic
"""

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views import View
import json
import logging

logger = logging.getLogger(__name__)


@method_decorator(csrf_exempt, name='dispatch')
@method_decorator(login_required, name='dispatch')
class LocationCheckinView(View):
    """
    evaluation_valueに基づく拡張チェックイン処理
    """
    
    def post(self, request):
        """
        ロケーションチェックイン処理
        
        Request body:
        {
            "location_id": int,
            "latitude": float,
            "longitude": float,
            "photo": str (base64) - evaluation_value=1の場合必須,
            "qr_code_data": str - evaluation_value=2の場合必須,
            "quiz_answer": str - evaluation_value=2の場合必須
        }
        """
        try:
            data = json.loads(request.body)
            location_id = data.get('location_id')
            user_lat = data.get('latitude')
            user_lon = data.get('longitude')
            
            if not all([location_id, user_lat, user_lon]):
                return JsonResponse({
                    'success': False,
                    'error': 'location_id, latitude, longitude are required'
                }, status=400)
            
            # ロケーション取得
            from .models import Location
            try:
                location = Location.objects.get(id=location_id)
            except Location.DoesNotExist:
                return JsonResponse({
                    'success': False,
                    'error': 'Location not found'
                }, status=404)
            
            # 距離チェック
            if not self._is_within_checkin_radius(location, user_lat, user_lon):
                return JsonResponse({
                    'success': False,
                    'error': 'Too far from location',
                    'required_radius': location.checkin_radius or 15.0
                }, status=400)
            
            # evaluation_valueに基づく要件検証
            from .location_interaction import validate_interaction_requirements
            validation_result = validate_interaction_requirements(location, data)
            
            if not validation_result['valid']:
                return JsonResponse({
                    'success': False,
                    'error': 'Interaction requirements not met',
                    'errors': validation_result['errors']
                }, status=400)
            
            # インタラクション処理
            interaction_result = self._process_interaction(location, data)
            
            # ポイント計算
            from .location_interaction import get_point_calculation
            point_info = get_point_calculation(location, interaction_result)
            
            # チェックイン記録保存
            checkin_record = self._save_checkin_record(
                request.user, location, user_lat, user_lon, 
                interaction_result, point_info
            )
            
            # レスポンス
            response_data = {
                'success': True,
                'checkin_id': checkin_record.id,
                'points_awarded': point_info['points_awarded'],
                'point_type': point_info['point_type'],
                'message': point_info['message'],
                'location_name': location.location_name,
                'interaction_type': location.evaluation_value or "0",
            }
            
            # インタラクション結果の詳細を追加
            if interaction_result:
                response_data['interaction_result'] = interaction_result
            
            return JsonResponse(response_data)
            
        except json.JSONDecodeError:
            return JsonResponse({
                'success': False,
                'error': 'Invalid JSON data'
            }, status=400)
        except Exception as e:
            logger.error(f"Checkin error: {e}")
            return JsonResponse({
                'success': False,
                'error': 'Internal server error'
            }, status=500)
    
    def _is_within_checkin_radius(self, location, user_lat, user_lon):
        """チェックイン範囲内かどうかを判定"""
        from math import radians, cos, sin, asin, sqrt
        
        # ロケーションの座標を取得
        if location.geom and location.geom.coords:
            loc_lon, loc_lat = location.geom.coords[0][:2]
        else:
            loc_lat = location.latitude
            loc_lon = location.longitude
        
        if not all([loc_lat, loc_lon]):
            return False
        
        # Haversine公式で距離計算
        def haversine(lon1, lat1, lon2, lat2):
            lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
            dlon = lon2 - lon1
            dlat = lat2 - lat1
            a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
            c = 2 * asin(sqrt(a))
            r = 6371000  # 地球の半径（メートル）
            return c * r
        
        distance = haversine(loc_lon, loc_lat, user_lon, user_lat)
        allowed_radius = location.checkin_radius or 15.0
        
        return distance <= allowed_radius
    
    def _process_interaction(self, location, data):
        """evaluation_valueに基づくインタラクション処理"""
        evaluation_value = location.evaluation_value or "0"
        result = {}
        
        if evaluation_value == "1":
            # 写真撮影処理
            photo_data = data.get('photo')
            if photo_data:
                result['photo_saved'] = True
                result['photo_filename'] = self._save_photo(photo_data, location)
            
        elif evaluation_value == "2":
            # QRコード + クイズ処理
            qr_data = data.get('qr_code_data')
            quiz_answer = data.get('quiz_answer')
            
            if qr_data and quiz_answer:
                result['qr_scanned'] = True
                result['quiz_answer'] = quiz_answer
                result['quiz_correct'] = self._check_quiz_answer(qr_data, quiz_answer)
        
        return result
    
    def _save_photo(self, photo_data, location):
        """写真データを保存（実装は要調整）"""
        import base64
        import os
        from django.conf import settings
        from datetime import datetime
        
        try:
            # Base64デコード
            photo_binary = base64.b64decode(photo_data)
            
            # ファイル名生成
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            filename = f"checkin_{location.id}_{timestamp}.jpg"
            
            # 保存先ディレクトリ
            photo_dir = os.path.join(settings.MEDIA_ROOT, 'checkin_photos')
            os.makedirs(photo_dir, exist_ok=True)
            
            # ファイル保存
            file_path = os.path.join(photo_dir, filename)
            with open(file_path, 'wb') as f:
                f.write(photo_binary)
            
            return filename
            
        except Exception as e:
            logger.error(f"Photo save error: {e}")
            return None
    
    def _check_quiz_answer(self, qr_data, quiz_answer):
        """クイズ回答の正答チェック（実装は要調整）"""
        # QRコードデータから正答を取得
        # 実際の実装では、QRコードに含まれるクイズIDから正答を取得
        try:
            import json
            qr_info = json.loads(qr_data)
            correct_answer = qr_info.get('correct_answer', '').lower()
            user_answer = quiz_answer.lower().strip()
            
            return correct_answer == user_answer
            
        except (json.JSONDecodeError, KeyError):
            # QRデータの形式が不正な場合はデフォルトで不正解
            return False
    
    def _save_checkin_record(self, user, location, lat, lon, interaction_result, point_info):
        """チェックイン記録を保存"""
        from .models import Useractions
        from datetime import datetime
        
        # Useractionsレコード作成/更新
        checkin_record, created = Useractions.objects.get_or_create(
            user=user,
            location=location,
            defaults={
                'checkin': True,
                'created_at': datetime.now(),
                'last_updated_at': datetime.now()
            }
        )
        
        if not created:
            checkin_record.checkin = True
            checkin_record.last_updated_at = datetime.now()
            checkin_record.save()
        
        return checkin_record
