from django.contrib.auth.hashers import make_password, check_password

from django.contrib.auth import get_user_model
User = get_user_model()

import uuid
from django.db import IntegrityError
from django.conf import settings
from django.urls import reverse
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError

from django.db import transaction
from rest_framework import serializers
from rest_framework_gis.serializers import GeoFeatureModelSerializer
from sqlalchemy.sql.functions import mode
from .models import Location2025, Location_line, Location_polygon, JpnAdminMainPerf, Useractions, GifuAreas, RogUser, UserTracks, GoalImages, CheckinImages,CustomUser,NewEvent,NewEvent2, Team, NewCategory, Category, Entry, Member, TempUser,EntryMember, AppVersion, UploadedImage
from drf_extra_fields.fields import Base64ImageField

#from django.contrib.auth.models import User
from .models import CustomUser
from django.contrib.auth import authenticate

from .models import TestModel
import logging
from django.shortcuts import get_object_or_404
from django.utils import timezone
from datetime import datetime, date


logger = logging.getLogger(__name__)

class LocationCatSerializer(serializers.ModelSerializer):
    class Meta:
        model=Location2025
        fields=['category',]


class LocationSerializer(serializers.ModelSerializer):
    # evaluation_valueに基づくインタラクション情報を追加
    interaction_type = serializers.SerializerMethodField()
    requires_photo = serializers.SerializerMethodField()
    requires_qr_code = serializers.SerializerMethodField()
    interaction_instructions = serializers.SerializerMethodField()
    
    # 追加フィールドのカスタムシリアライズ
    has_photos = serializers.SerializerMethodField()
    has_videos = serializers.SerializerMethodField()
    photos_list = serializers.SerializerMethodField()
    videos_list = serializers.SerializerMethodField()
    tags_list = serializers.SerializerMethodField()
    
    # 位置情報の緯度経度
    latitude_float = serializers.SerializerMethodField()
    longitude_float = serializers.SerializerMethodField()
    
    # フィールド名の別名対応
    webcontent = serializers.SerializerMethodField()
    zip = serializers.SerializerMethodField()
    s3_name = serializers.SerializerMethodField()
    
    def get_webcontent(self, obj):
        """websiteフィールドをwebcontentとして返す"""
        return obj.website
        
    def get_zip(self, obj):
        """zip_codeフィールドをzipとして返す"""
        return obj.zip_code
    
    def get_s3_name(self, obj):
        """S3ファイル名を生成して返す（event_nameのローマ字表記）"""
        if not obj.event:
            return None
            
        # NewEvent2のs3_nameフィールドを参照
        if hasattr(obj.event, 's3_name') and obj.event.s3_name:
            return obj.event.s3_name
            
        # フォールバック: event_nameをローマ字に変換
        if obj.event.event_name:
            s3_name = self._convert_japanese_to_romaji(obj.event.event_name)
            return s3_name
            
        # 最終フォールバック: イベントコード
        return obj.event.event_code
    
    def _convert_japanese_to_romaji(self, japanese_text):
        """日本語をローマ字に変換する"""
        # 基本的な日本語→ローマ字変換テーブル
        conversion_table = {
            # 地名
            '岐阜': 'gifu',
            '大垣': 'ogaki',
            '多治見': 'tajimi',
            '関': 'seki',
            '中津川': 'nakatsugawa',
            '美濃': 'mino',
            '瑞浪': 'mizunami',
            '羽島': 'hashima',
            '恵那': 'ena',
            '美濃加茂': 'minokamo',
            '土岐': 'toki',
            '各務原': 'kakamigahara',
            '可児': 'kani',
            '山県': 'yamagata',
            '瑞穂': 'mizuho',
            '飛騨': 'hida',
            '本巣': 'motosu',
            '郡上': 'gujo',
            '下呂': 'gero',
            '海津': 'kaizu',
            
            # 一般的な単語
            'ロゲイニング': 'rogaining',
            'ロゲ': 'roge',
            'イベント': 'event',
            '大会': 'taikai',
            '競技': 'kyogi',
            'スポーツ': 'sports',
            'アウトドア': 'outdoor',
            'ハイキング': 'hiking',
            'ウォーキング': 'walking',
            'ランニング': 'running',
            'マラソン': 'marathon',
            'トレイル': 'trail',
            'オリエンテーリング': 'orienteering',
            'ナビゲーション': 'navigation',
            'チェックポイント': 'checkpoint',
            'ゴール': 'goal',
            'スタート': 'start',
            'チーム': 'team',
            'ファミリー': 'family',
            'ジュニア': 'junior',
            'シニア': 'senior',
            '初心者': 'beginner',
            '上級者': 'advanced',
            '中級者': 'intermediate',
            
            # 年号
            '２０２５': '2025',
            '2025': '2025',
            '２０２４': '2024',
            '2024': '2024',
            '２０２６': '2026',
            '2026': '2026',
            '２０２７': '2027',
            '2027': '2027',
            '２０２８': '2028',
            '2028': '2028',
            '２０２９': '2029',
            '2029': '2029',
            '２０３０': '2030',
            '2030': '2030',
            
            # 月
            '１月': 'january',
            '２月': 'february',
            '３月': 'march',
            '４月': 'april',
            '５月': 'may',
            '６月': 'june',
            '７月': 'july',
            '８月': 'august',
            '９月': 'september',
            '１０月': 'october',
            '１１月': 'november',
            '１２月': 'december',
            
            # その他
            '春': 'spring',
            '夏': 'summer',
            '秋': 'autumn',
            '冬': 'winter',
            '第': 'dai',
            '回': 'kai',
            '杯': 'hai',
            '記念': 'kinen',
            '特別': 'tokubetsu',
            '公式': 'koshiki',
            '練習': 'renshu',
            '体験': 'taiken'
        }
        
        result = japanese_text.lower()
        
        # 変換テーブルを使用して変換
        for japanese, romaji in conversion_table.items():
            result = result.replace(japanese, romaji)
        
        # 記号の変換
        result = result.replace(' ', '_')
        result = result.replace('-', '_')
        result = result.replace('　', '_')  # 全角スペース
        result = result.replace('・', '_')
        result = result.replace('/', '_')
        result = result.replace('\\', '_')
        result = result.replace('(', '_')
        result = result.replace(')', '_')
        result = result.replace('（', '_')
        result = result.replace('）', '_')
        result = result.replace('[', '_')
        result = result.replace(']', '_')
        result = result.replace('【', '_')
        result = result.replace('】', '_')
        result = result.replace(':', '_')
        result = result.replace('：', '_')
        result = result.replace(';', '_')
        result = result.replace('；', '_')
        result = result.replace(',', '_')
        result = result.replace('，', '_')
        result = result.replace('.', '_')
        result = result.replace('。', '_')
        result = result.replace('!', '_')
        result = result.replace('！', '_')
        result = result.replace('?', '_')
        result = result.replace('？', '_')
        
        # 連続するアンダースコアを単一に
        while '__' in result:
            result = result.replace('__', '_')
        
        # 先頭と末尾のアンダースコアを削除
        result = result.strip('_')
        
        # 空文字列の場合は'event'を返す
        if not result:
            result = 'event'
            
        return result
    
    class Meta:
        model=Location2025
        fields=[
            # 基本フィールド
            'id', 'cp_number', 'event', 'cp_name', 's3_name','category', 'sub_loc_id', 'subcategory',
            'latitude', 'longitude', 'location', 'address',
            'checkin_point', 'buy_point',
            'checkin_radius', 'auto_checkin',
            'shop_closed', 'shop_shutdown', 'opening_hours',
            'phone', 'website', 'facility', 'description', 'remark',
            # 住所詳細フィールド
            'zip_code', 'prefecture', 'area', 'city',
            # 追加フィールド
            'photos', 'videos', 'tags', 'evaluation_value', 'hidden_location',
            # 管理フィールド
            'is_active', 'sort_order', 'csv_source_file', 'csv_upload_date', 'csv_upload_user',
            'created_at', 'updated_at', 'created_by', 'updated_by',
            # カスタムフィールド
            'interaction_type', 'requires_photo', 'requires_qr_code', 'interaction_instructions',
            'has_photos', 'has_videos', 'photos_list', 'videos_list', 'tags_list',
            'latitude_float', 'longitude_float', 'webcontent', 'zip'
        ]
        
    def get_latitude_float(self, obj):
        """位置情報から緯度を取得"""
        if obj.location:
            return obj.location.y
        return obj.latitude
        
    def get_longitude_float(self, obj):
        """位置情報から経度を取得"""
        if obj.location:
            return obj.location.x
        return obj.longitude
        
    def get_has_photos(self, obj):
        """写真データの有無を返す"""
        return bool(obj.photos and obj.photos.strip())
    
    def get_has_videos(self, obj):
        """動画データの有無を返す"""
        return bool(obj.videos and obj.videos.strip())
    
    def get_photos_list(self, obj):
        """写真ファイル名をリストで返す"""
        if not obj.photos or not obj.photos.strip():
            return []
        # カンマ区切りで分割してリストとして返す
        return [photo.strip() for photo in obj.photos.split(',') if photo.strip()]
    
    def get_videos_list(self, obj):
        """動画ファイル名をリストで返す"""
        if not obj.videos or not obj.videos.strip():
            return []
        # カンマ区切りで分割してリストとして返す
        return [video.strip() for video in obj.videos.split(',') if video.strip()]
        
    def get_tags_list(self, obj):
        """タグをリストで返す"""
        if not obj.tags or not obj.tags.strip():
            return []
        # カンマ区切りで分割してリストとして返す
        return [tag.strip() for tag in obj.tags.split(',') if tag.strip()]
        
    def get_interaction_type(self, obj):
        """evaluation_valueに基づくインタラクションタイプを返す"""
        try:
            from .location_interaction import get_interaction_type
            return get_interaction_type(obj)['type']
        except ImportError:
            return obj.evaluation_value or "0"
    
    def get_requires_photo(self, obj):
        """写真撮影が必要かどうかを返す"""
        try:
            from .location_interaction import get_interaction_type
            return get_interaction_type(obj)['requires_photo']
        except ImportError:
            return obj.evaluation_value == "1"
    
    def get_requires_qr_code(self, obj):
        """QRコードスキャンが必要かどうかを返す"""
        try:
            from .location_interaction import should_use_qr_code
            return should_use_qr_code(obj)
        except ImportError:
            return obj.evaluation_value == "2" or getattr(obj, 'use_qr_code', False)
    
    def get_interaction_instructions(self, obj):
        """インタラクション手順を返す"""
        try:
            from .location_interaction import get_interaction_type
            return get_interaction_type(obj)['instructions']
        except ImportError:
            evaluation_value = obj.evaluation_value or "0"
            if evaluation_value == "1":
                return "商品の写真を撮影してください。買い物をすることでポイントを獲得できます"
            elif evaluation_value == "2":
                return "QRコードをスキャンしてください"
            else:
                return "この場所でチェックインしてポイントを獲得してください"


class Location_lineSerializer(GeoFeatureModelSerializer):
    class Meta:
        model=Location_line
        geo_field='geom'
        fields="__all__"

class Location_polygonSerializer(GeoFeatureModelSerializer):
    class Meta:
        model=Location_polygon
        geo_field='geom'
        fields="__all__"


class JPN_main_perfSerializer(serializers.ModelSerializer):
    class Meta:
        model=JpnAdminMainPerf
        fields=['id', 'adm0_en', 'adm0_ja', 'adm0_pcode', 'adm1_en', 'adm1_ja', 'adm1_pcode']

# class JPN_sub_perSerializer(serializers.ModelSerializer):
#     class Meta:
#         model=JpnSubPerf
#         fields=['id', 'adm0_en', 'adm0_ja', 'adm0_pcode', 'adm1_en', 'adm1_ja', 'adm1_pcode', 'adm2_ja', 'adm2_en', 'adm2_pcode']


# class JPN_perfSerializer(serializers.ModelSerializer):
#     class Meta:
#         model=JpnAdminPerf
#         fields=['id','et_id', 'et_right', 'et_left', 'adm2_l', 'adm1_l', 'adm0_l', 'adm0_r', 'adm1_r', 'adm2_r', 'admlevel']


class GifuAreaSerializer(serializers.ModelSerializer):
    class Meta:
        model= GifuAreas
        fields=['id', 'adm0_ja', 'adm0_pcode', 'adm1_en', 'adm1_ja', 'adm1_pcode', 'adm2_ja', 'adm2_en', 'adm2_pcode', 'area_nm']

class UserRegistrationSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=True, validators=[validate_password])
    password2 = serializers.CharField(write_only=True, required=True, validators=[validate_password])
    
    class Meta:
        model = CustomUser
        fields = ('email', 'password', 'password2', 'firstname', 'lastname', 'date_of_birth', 'female')
        extra_kwargs = {
            'email': {'required': True},
            'firstname': {'required': True},
            'lastname': {'required': True},
            'date_of_birth': {'required': True},
        }

    def validate(self, attrs):
        if attrs['password'] != attrs['password2']:
            raise serializers.ValidationError({"password": "Password fields didn't match."})

        try:
            validate_password(attrs['password'])
        except ValidationError as e:
            raise serializers.ValidationError({"password": list(e.messages)})

        return attrs

    def validate_email(self, value):
        if CustomUser.objects.filter(email=value).exists() or TempUser.objects.filter(email=value).exists():
            raise serializers.ValidationError("この電子メールアドレスは既に使用されています。")
        return value

    def create(self, validated_data):
        raw_password = validated_data.get('password')

        # デバッグコード
        hashed_password = make_password(raw_password)
        print(f"Hashed password during registration: {hashed_password}")
        is_valid = check_password(raw_password, hashed_password)
        print(f"Password is valid during registration: {is_valid}")

        validated_data['password'] = hashed_password
        return super(UserRegistrationSerializer, self).create(validated_data)

        #validated_data['password'] = make_password(validated_data.get('password'))
        #return super(UserRegistrationSerializer, self).create(validated_data)

#        try:
#            with transaction.atomic():
#                password = validated_data['password'].encode('utf-8').decode('utf-8')
#
#                user = CustomUser.objects.create_user(
#                    email=validated_data['email'],
#                    password=password,  # validated_data['password'],
#                    firstname=validated_data['firstname'],
#                    lastname=validated_data['lastname'],
#                    date_of_birth=validated_data['date_of_birth'],
#                    female=validated_data.get('female', False),
#                    group=''  # この値は必要に応じて変更してください
#                )
#                logger.debug(f"Creating user with data: {validated_data}")
#                user.set_password(validated_data['password'])
#                user.save()
#
#            return user
#        except ValidationError as e:
#            raise serializers.ValidationError({"password": list(e.messages)})


#class CreateUserSerializer(serializers.ModelSerializer):
#    class Meta:
#        model = CustomUser
#        fields = ('email', 'password')
#        extra_kwargs = {'password': {'write_only': True}}
#
#    def create(self, validated_data):
#        user = CustomUser.objects.create_user(validated_data['email'],validated_data['password'], '大垣-初心者','','')
#        return user

class TempUserRegistrationSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)

    class Meta:
        model = TempUser
        fields = ('email', 'password', 'firstname', 'lastname', 'date_of_birth', 'female')

    def create(self, validated_data):
        # パスワードのハッシュ化はviewで行うので、ここではそのまま保存
        return TempUser.objects.create(**validated_data)

        #validated_data['verification_code'] = str(uuid.uuid4())
        #raw_password = validated_data.get('password')
        #hashed_password = make_password(raw_password)
        #validated_data['password'] = hashed_password
        #return TempUser.objects.create(**validated_data)


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ('id','email', 'is_rogaining' ,'group', 'zekken_number', 'event_code', 'team_name', 'is_staff')

class GolaImageSerializer(serializers.ModelSerializer):
    goalimage = Base64ImageField(max_length=None, use_url=True)

    class Meta:
        model = GoalImages
        fields="__all__"
    
    def get_goalimage_url_old(self, car):
        request = self.context.get('request')
        photo_url = GoalImages.goalimage.url
        return request.build_absolute_uri(photo_url)

    def get_goalimage_url(self, obj):
        request = self.context.get('request')
        if request is None:
            logger.warning("Request not found in serializer context")
            return None

        try:
            photo_url = obj.goalimage.url
            absolute_url = request.build_absolute_uri(photo_url)
            logger.info(f"Generated URL for goalimage: {absolute_url}")
            return absolute_url
        except AttributeError as e:
            logger.error(f"Error generating URL for goalimage: {str(e)}")
            return None

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        representation['goalimage_url'] = self.get_goalimage_url(instance)
        logger.debug(f"Serialized data: {representation}")
        return representation

class CheckinImageSerializer(serializers.ModelSerializer):
    checkinimage = Base64ImageField(max_length=None, use_url=True)
    class Meta:
        model = CheckinImages
        fields="__all__"
    
    def get_checkinimage_url(self, car):
        request = self.context.get('request')
        photo_url = CheckinImages.checkinimage.url
        return request.build_absolute_uri(photo_url)


class RogUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = RogUser
        fields = ('id','user', 'paid',)


class LoginUserSerializer(serializers.Serializer):
    #email = serializers.CharField()
    email = serializers.EmailField()
    password = serializers.CharField()

    def validate(self, data):
        email = data.get('email')
        password = data.get('password')
        
        if email and password:
            user = authenticate(username=email, password=password)
            if user:
                if user.is_active:
                    return user
                raise serializers.ValidationError("User account is disabled.")
            else:
                # Check if the user exists
                try:
                    user_obj = User.objects.get(email=email)
                    raise serializers.ValidationError("Incorrect password.")
                except User.DoesNotExist:
                    raise serializers.ValidationError("User with this email does not exist.")
        else:
            raise serializers.ValidationError("Must include 'email' and 'password'.")





class UseractionsSerializer(serializers.ModelSerializer):

    user = UserSerializer(read_only=True)
    #location = LocationSerializer(read_only=True)
    location = serializers.RelatedField(source='Location', read_only=True)
    #location = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = Useractions
        fields = ('id', 'user', 'location', 'wanttogo', 'like', 'checkin', 'order',)

class UserDestinationSerializer(serializers.ModelSerializer):

    #user = UserSerializer(read_only=True)
    location = LocationSerializer(read_only=True)
    #location = serializers.RelatedField(source='Location', read_only=True)
    #location = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = Useractions
        fields = ('id', 'user', 'location', 'wanttogo', 'like', 'checkin')

class LocationEventNameSerializer(serializers.ModelSerializer):
    class Meta:
        model = Location2025
        fields = ('id', 'event_name',)


class UserTracksSerializer(GeoFeatureModelSerializer):
    user_id = serializers.IntegerField()
    class Meta:
        model=UserTracks
        geo_field = 'geom'
        fields = ["user_id",]

    def create(self, validated_data):
        user_id = validated_data.pop("user_id", None)
        user = CustomUser.objects.get(id=user_id)
        return UserTracks.objects.create(user=user, **validated_data)

    
class TestSerialiser(serializers.ModelSerializer):

    class Meta:
        model = TestModel
        fields = ('id', 'testbane', 'wanttogo', 'like', 'checkin')


class ChangePasswordSerializer(serializers.Serializer):
    model = CustomUser

    """
    Serializer for password change endpoint.
    """
    old_password = serializers.CharField(required=True)
    new_password = serializers.CharField(required=True)


class RegistrationSerializer(serializers.ModelSerializer):
    password2 = serializers.CharField(style={"input_type": "password"}, write_only=True)

    class Meta:
        model = CustomUser
        fields = ['email', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group', 'password', 'password2']
        extra_kwargs = {
            'password': {'write_only': True}
        }

    def save(self):
        user = CustomUser(email=self.validated_data['email'], is_rogaining=self.validated_data['is_rogaining'], zekken_number=self.validated_data['zekken_number'], event_code=self.validated_data['event_code'], team_name=self.validated_data['team_name'], group=self.validated_data['group'])
        password = self.validated_data['password']
        password2 = self.validated_data['password2']
        if password != password2:
            raise serializers.ValidationError({'password': 'Passwords must match.'})
        user.set_password(password)
        user.save()
        return user

class NewCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = NewCategory
        fields = ['id','category_name', 'category_number', 'duration', 'num_of_member', 'family', 'female']
        #fields = ['id','category_name', 'category_number']

class NewEvent2Serializer(serializers.ModelSerializer):
    # API変更要求書対応: deadline_datetime フィールド追加
    deadline_datetime = serializers.DateTimeField(source='deadlineDateTime', read_only=True)
    # Supervisor web app compatibility
    code = serializers.CharField(source='event_name', read_only=True)
    name = serializers.CharField(source='event_name', read_only=True)
    
    class Meta:
        model = NewEvent2
        fields = [
            'id', 'event_name', 'start_datetime', 'end_datetime', 
            'deadlineDateTime', 'deadline_datetime', 'status', 'public', 
            'hour_3', 'hour_5', 'class_general', 'class_family', 
            'class_solo_male', 'class_solo_female',
            'code', 'name'  # Supervisor compatibility
        ]
        
    def to_representation(self, instance):
        """レスポンス形式を調整"""
        data = super().to_representation(instance)
        
        # publicフィールドからstatusへの移行サポート
        if not data.get('status') and data.get('public'):
            data['status'] = 'public'
        elif not data.get('status'):
            data['status'] = 'draft'
            
        return data

class NewEventSerializer(serializers.ModelSerializer):
    class Meta:
        model = NewEvent
        fields = ['event_name', 'start_datetime', 'end_datetime']

class TeamSerializer(serializers.ModelSerializer):
    category = serializers.PrimaryKeyRelatedField(queryset=NewCategory.objects.all())

    #category = serializers.IntegerField()
    #category = NewCategorySerializer(read_only=True)
    #category_id = serializers.PrimaryKeyRelatedField(
    #    queryset=NewCategory.objects.all(),
    #    source='category',
    #    write_only=True
    #)
    owner = serializers.PrimaryKeyRelatedField(read_only=True)


    class Meta:
        model = Team
        fields = ['id','team_name', 'category', 'owner']
        read_only_fields = ['id', 'owner']

    def to_representation(self, instance):
        ret = super().to_representation(instance)
        if instance.category:
            ret['category'] = {
                'id': instance.category.id,
                'category_name': instance.category.category_name,
                'category_number': instance.category.category_number,
                'duration': instance.category.duration,
                'num_of_member':instance.category.num_of_member,
                'family':instance.category.family,
                'female':instance.category.female
            }
        else:
            ret['category'] = None
        ret['owner'] = CustomUserSerializer(instance.owner).data
        return ret
    
    def validate_category(self, value):
        if not isinstance(value, NewCategory):
            raise serializers.ValidationError("Invalid category")
        return value

        #if not NewCategory.objects.filter(id=value).exists():
        #    raise serializers.ValidationError("Invalid category ID")
        #return value


    def create(self, validated_data):
        return Team.objects.create(**validated_data)

        #category_id = validated_data.pop('category')
        #category = get_object_or_404(NewCategory, id=category_id)
        #team = Team.objects.create(category=category, **validated_data)
        #team.category = category
        #return team


        #category = validated_data.pop('category')
        #team = Team.objects.create(category=category, **validated_data)
        #return team

        #logger.debug(f"Creating team with data: {validated_data}")
        #validated_data['owner'] = self.context['request'].user
        #return super().create(validated_data)

    def update(self, instance, validated_data):
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        return instance

        #if 'category' in validated_data:
        #    category_id = validated_data.pop('category')
        #    category = get_object_or_404(NewCategory, id=category_id)
        #    instance.category = category
        #return super().update(instance, validated_data)

        #if 'category' in validated_data:
        #    instance.category = validated_data.pop('category')
        #return super().update(instance, validated_data)

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ['category_name', 'category_number', 'duration', 'num_of_member', 'family', 'female']

class EntrySerializer(serializers.ModelSerializer):
    team = serializers.PrimaryKeyRelatedField(queryset=Team.objects.all())
    event = serializers.PrimaryKeyRelatedField(queryset=NewEvent2.objects.all())
    category = serializers.PrimaryKeyRelatedField(queryset=NewCategory.objects.all())
    owner = serializers.PrimaryKeyRelatedField(read_only=True)
    date = serializers.DateTimeField(required=False, allow_null=True)  # DateTimeFieldを使用
    zekken_number = serializers.IntegerField() 

    class Meta:
        model = Entry
        fields = [
            'id', 'team', 'event', 'category', 'date', 'zekken_number', 'owner',
            'is_active', 'hasParticipated', 'hasGoaled', 
            # API変更要求書対応: 新フィールド追加
            'staff_privileges', 'can_access_private_events', 'team_validation_status'
        ]
        read_only_fields = ['id', 'owner']

    def validate_date(self, value):
        if isinstance(value, str):
            try:
                # 文字列をdatetimeオブジェクトに変換
                value = datetime.strptime(value, "%Y-%m-%d")
            except ValueError:
                raise serializers.ValidationError("Invalid date format. Use YYYY-MM-DD.")

        if isinstance(value, date) and not isinstance(value, datetime):
            # dateオブジェクトをdatetimeオブジェクトに変換
            value = datetime.combine(value, datetime.min.time())

        if isinstance(value, datetime) and timezone.is_naive(value):
            return timezone.make_aware(value, timezone.get_current_timezone())
        return value

    def validate_team(self, value):
        if not value.members.exists():
            raise serializers.ValidationError("チームにメンバーが登録されていません。")
        return value

    def validate(self, data):
        team = data.get('team')
        event = data.get('event')
        category = data.get('category')
        entry_date = data.get('date')
        if isinstance(entry_date, datetime):
            entry_date = entry_date.date()
        elif isinstance(entry_date, str):
            entry_date = datetime.strptime(entry_date, "%Y-%m-%d").date()

        logger.debug("test-0")
        logger.debug(f"==== start:{event.start_datetime.date()} <= entry_date : {entry_date} <= end:{event.end_datetime.date()} ?? ====")

        if entry_date < event.start_datetime.date() or entry_date > event.end_datetime.date():
            raise serializers.ValidationError(f"日付は{event.start_datetime.date()}から{event.end_datetime.date()}の間である必要があります。")

        logger.debug("test-1")

        try:
            logger.debug(f"Parsed data: team={team}, event={event}, category={category}, ")

            owner = self.context['request'].user
            zekken_number = data.get('zekken_number')

            logger.debug(f"entry_date={entry_date}, owner={owner}, zekken_number={zekken_number}")

        except Exception:
            raise serializers.ValidationError(f"何らかのエラーが発生しました")

        # Check if team, event, and category exist
        if not Team.objects.filter(id=team.id).exists():
            raise serializers.ValidationError("指定されたチームは存在しません。")
        if not NewEvent2.objects.filter(id=event.id).exists():
            raise serializers.ValidationError("指定されたイベントは存在しません。")
        if not NewCategory.objects.filter(id=category.id).exists():
            raise serializers.ValidationError("指定されたカテゴリーは存在しません。")

        # Check for unique constraint
        if Entry.objects.filter(team=team, event=event, date__date=entry_date, owner=owner).exists():
            raise serializers.ValidationError("既に登録済みです。")

        # Validate zekken_number
        if zekken_number is not None:
            if zekken_number <= 0:
                raise serializers.ValidationError("ゼッケン番号は正の整数である必要があります。")
        #    if Entry.objects.filter(event=event, zekken_number=zekken_number).exists():
        #        raise serializers.ValidationError("このゼッケン番号は既に使用されています。")

        return data

    def to_internal_value(self, data):
        # dateフィールドが文字列で来た場合の処理
        if 'date' in data and isinstance(data['date'], str):
            try:
                # 文字列をdatetimeオブジェクトに変換
                data['date'] = datetime.strptime(data['date'], "%Y-%m-%d")
            except ValueError:
                raise serializers.ValidationError({"date": "無効な日付形式です。YYYY-MM-DD形式を使用してください。"})

        return super().to_internal_value(data)

    def to_representation(self, instance):
        ret = super().to_representation(instance)
        ret['team'] = TeamSerializer(instance.team).data
        ret['event'] = NewEvent2Serializer(instance.event).data
        ret['category'] = NewCategorySerializer(instance.category).data
        ret['owner'] = CustomUserSerializer(instance.owner).data

        if isinstance(ret['date'], datetime):
            ret['date'] = ret['date'].date().isoformat()
        elif isinstance(ret['date'], date):
            ret['date'] = ret['date'].isoformat()
        return ret

        #if isinstance(ret['date'], datetime):
        #    ret['date'] = ret['date'].date().isoformat()
        #return ret

    #def to_representation(self, instance):
    #    ret = super().to_representation(instance)
    #    ret['team'] = instance.team.team_name
    #    ret['event'] = instance.event.event_name
    #    ret['category'] = instance.category.category_name
    #    ret['owner'] = instance.owner.email
    #    return ret

class CustomUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ['id','email', 'firstname', 'lastname', 'date_of_birth', 'female', 'is_staff']
        read_only_fields = ['id','email']

class TeamDetailSerializer(serializers.ModelSerializer):
    category = NewCategorySerializer(read_only=True)
    
    class Meta:
        model = Team
        fields = ['id', 'zekken_number', 'team_name', 'category']

class UserDetailSerializer(serializers.ModelSerializer):
    event_date = serializers.SerializerMethodField()
    last_goal_time = serializers.SerializerMethodField()
    
    class Meta:
        model = CustomUser
        fields = ['id','email', 'firstname', 'lastname', 'date_of_birth', 'female', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group', 'is_staff', 'event_date', 'last_goal_time']
        read_only_fields = ('id', 'email')
    
    def get_event_date(self, obj):
        """イベント日付を取得（ハードコーディングの値を返す）"""
        # ハードコーディングされた日付をDateTimeとして返す
        from datetime import datetime
        return datetime(2025, 5, 17).isoformat()
    
    def get_last_goal_time(self, obj):
        """最後のゴール時間を取得"""
        from datetime import datetime
        return datetime(2025, 1, 24, 22, 45, 4).isoformat()

class UserUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ['firstname', 'lastname', 'date_of_birth', 'female']
        extra_kwargs = {'email': {'read_only': True}}

    def update(self, instance, validated_data):
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        return instance

class MemberCreationSerializer(serializers.Serializer):
    #email = serializers.EmailField()
    email = serializers.EmailField(allow_blank=True, required=False)

    firstname = serializers.CharField(required=False, allow_blank=True)
    lastname = serializers.CharField(required=False, allow_blank=True)
    date_of_birth = serializers.DateField(required=False)
    female = serializers.BooleanField(required=False)


class MemberWithUserSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)

    class Meta:
        model = Member
        fields = ['user', 'team']

class MemberSerializer(serializers.ModelSerializer):
    email = serializers.EmailField(write_only=True)
    firstname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
    lastname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
    date_of_birth = serializers.DateField(required=False, allow_null=True)
    female = serializers.BooleanField(required=False)

    class Meta:
        model = Member
        fields = ['id', 'email', 'firstname', 'lastname', 'date_of_birth', 'female']

    def validate_firstname(self, value):
        return value or None

    def validate_lastname(self, value):
        return value or None

    def create(self, validated_data):
        email = validated_data.pop('email')
        team = self.context['team']
        
        # 既存のユーザーを探すか、新しいユーザーを作成
        user, created = CustomUser.objects.get_or_create(email=email)
        
        # ユーザーが新しく作成された場合のみ、追加情報を更新
        if created:
            user.firstname = validated_data.get('firstname', '')
            user.lastname = validated_data.get('lastname', '')
            user.date_of_birth = validated_data.get('date_of_birth')
            user.female = validated_data.get('female', False)
            user.save()

        # メンバーを作成
        member = Member.objects.create(
            user=user,
            team=team,
            firstname=validated_data.get('firstname'),
            lastname=validated_data.get('lastname'),
            date_of_birth=validated_data.get('date_of_birth'),
            female=validated_data.get('female', False)
        )

        return member
        # メンバーを作成して返す
        #class MemberCreationSerializerreturn Member.objects.create(user=user, team=team)

    def update(self, instance, validated_data):
        user_data = validated_data.pop('user', {})
        user = instance.user

        for attr, value in user_data.items():
            setattr(user, attr, value)
        user.save()

        return super().update(instance, validated_data)

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        representation['email'] = instance.user.email
        representation['firstname'] = instance.user.firstname
        representation['lastname'] = instance.user.lastname
        representation['date_of_birth'] = instance.user.date_of_birth
        representation['female'] = instance.user.female
        representation['is_staff'] = instance.user.is_staff
        return representation



class MemberSerializerOld(serializers.ModelSerializer):
    user = CustomUserSerializer(read_only=True)
    firstname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
    lastname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
    date_of_birth = serializers.DateField(required=False, allow_null=True)
    female = serializers.BooleanField(required=False)


    #team = TeamDetailSerializer(read_only=True)

    #email = serializers.EmailField(write_only=True, required=False)
    #firstname = serializers.CharField(write_only=True, required=False)
    #lastname = serializers.CharField(write_only=True, required=False)
    #date_of_birth = serializers.DateField(write_only=True, required=False)
    #female = serializers.BooleanField(write_only=True, required=False)

    class Meta:
        model = Member
        fields = ['id','email','firstname','lastname','date_of_birth','female']
        #read_only_fields = ['id', 'team']


    '''
    def create(self, validated_data):
        team = validated_data['team']
        email = validated_data.get('email')

        if email.startswith('dummy_'):
            user, _ = CustomUser.objects.get_or_create(
                email=email,
                defaults={**user_data, 'is_active': True}
            )
        else:
            user, _ = CustomUser.objects.get_or_create(
                email=email,
                defaults={**user_data, 'is_active': False}
            )
        
        member = Member.objects.create(user=user, **validated_data)
        return member
    '''

    def create(self, validated_data):
        email = validated_data.pop('email')
        team = self.context['team']

        # 既存のユーザーを探すか、新しいユーザーを作成
        user, created = CustomUser.objects.get_or_create(email=email)

        # メンバーを作成
        member = Member.objects.create(
            user=user,
            team=team,
            firstname=validated_data.get('firstname', ''),
            lastname=validated_data.get('lastname', ''),
            date_of_birth=validated_data.get('date_of_birth'),
            female=validated_data.get('female', False)
        )

        return member


    def update(self, instance, validated_data):
        user_data = validated_data.pop('user', {})
        user = instance.user

        for attr, value in user_data.items():
            setattr(user, attr, value)
        user.save()

        return super().update(instance, validated_data)


        #if user.email.startswith('dummy_'):  # dummy_ で始まるメールアドレスの場合のみ更新
        #    for attr, value in user_data.items():
        #        setattr(user, attr, value)
        #    user.save()
        #else:
        #    raise serializers.ValidationError("このユーザーの情報は更新できません。")

        #return super().update(instance, validated_data)

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        representation['email'] = instance.user.email
        return representation

'''
    def to_representation(self, instance):
        representation = super().to_representation(instance)
        user_data = representation['user']
        return {
            'id': representation['id'],
            'email': user_data['email'],
            'firstname': user_data['firstname'],
            'lastname': user_data['lastname'],
            'date_of_birth': user_data['date_of_birth'],
            'female': user_data['female'],
            'team': representation['team']
        }
'''

class EntryMemberSerializer(serializers.ModelSerializer):
    class Meta:
        model = EntryMember
        fields = ['id', 'entry', 'member', 'is_temporary']


class TempUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = TempUser
        #fields = ['id','email', 'password', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group', 'firstname', 'lastname', 'date_of_birth', 'female', 'verification_code', 'created_at', 'expires_at']
        fields = ['email', 'password', 'firstname', 'lastname', 'date_of_birth', 'female', 'verification_code']

class EntryCreationSerializer(serializers.Serializer):
    owner_email = serializers.EmailField()
    event_name = serializers.CharField()
    category_name = serializers.CharField()
    team_name = serializers.CharField()
    zekken_number = serializers.CharField()
    date = serializers.DateField()
    members = serializers.ListField(child=serializers.DictField())

    def create(self, validated_data):
        owner = CustomUser.objects.get(email=validated_data['owner_email'])
        event = NewEvent2.objects.get(event_name=validated_data['event_name'])
        category = NewCategory.objects.get(category_name=validated_data['category_name'])

        # Create or get team
        team, _ = Team.objects.get_or_create(
            zekken_number=validated_data['zekken_number'],
            category=category,
            defaults={'team_name': validated_data['team_name'], 'owner': owner}
        )

        # Create or update entry
        entry, _ = Entry.objects.update_or_create(
            owner=owner,
            team=team,
            event=event,
            date=validated_data['date'],
            defaults={'category': category}
        )

        # Process members
        for member_data in validated_data['members']:
            user, created = CustomUser.objects.get_or_create(
                email=member_data.get('email'),
                defaults={
                    'firstname': member_data['firstname'],
                    'lastname': member_data['lastname'],
                    'date_of_birth': member_data['date_of_birth']
                }
            )

            if created:
                TempUser.objects.create(
                    email=user.email,
                    firstname=user.firstname,
                    lastname=user.lastname,
                    date_of_birth=user.date_of_birth
                )
                # Send invitation email here

            member, _ = NewMember.objects.get_or_create(
                user=user,
                team=team,
                defaults={'is_temporary': created}
            )

            EntryMember.objects.get_or_create(entry=entry, member=member)

        return entry

class PasswordResetRequestSerializer(serializers.Serializer):
    email = serializers.EmailField()

class PasswordResetConfirmSerializer(serializers.Serializer):
    new_password = serializers.CharField(write_only=True)
    confirm_password = serializers.CharField(write_only=True)

    def validate(self, data):
        if data['new_password'] != data['confirm_password']:
            raise serializers.ValidationError("Passwords do not match")
        validate_password(data['new_password'])
        return data

class UserLastGoalTimeSerializer(serializers.Serializer):
    user_email = serializers.EmailField()
    last_goal_time = serializers.DateTimeField()

class LoginUserSerializer_old(serializers.Serializer):
    identifier = serializers.CharField(required=True)  # メールアドレスまたはゼッケン番号
    password = serializers.CharField(required=True)

    def validate(self, data):
        identifier = data.get('identifier')
        password = data.get('password')

        if not identifier or not password:
            raise serializers.ValidationError('認証情報を入力してください。')

        # ゼッケン番号かメールアドレスかを判定
        if '@' in identifier:
            # メールアドレスの場合
            user = authenticate(username=identifier, password=password)
        else:
            # ゼッケン番号の場合
            try:
                # ゼッケン番号からユーザーを検索
                user = CustomUser.objects.filter(zekken_number=identifier).first()
                if user:
                    # パスワード認証
                    if not user.check_password(password):
                        user = None
            except ValueError:
                user = None

        if user and user.is_active:
            return user
        elif user and not user.is_active:
            raise serializers.ValidationError('アカウントが有効化されていません。')
        else:
            raise serializers.ValidationError('認証情報が正しくありません。')


class AppVersionSerializer(serializers.ModelSerializer):
    """アプリバージョン管理シリアライザー"""
    
    class Meta:
        model = AppVersion
        fields = [
            'id', 'version', 'platform', 'build_number', 
            'is_latest', 'is_required', 'update_message', 
            'download_url', 'release_date', 'created_at'
        ]
        read_only_fields = ['id', 'created_at']


class AppVersionCheckSerializer(serializers.Serializer):
    """アプリバージョンチェック用シリアライザー"""
    
    current_version = serializers.CharField(max_length=20, help_text="現在のアプリバージョン")
    platform = serializers.ChoiceField(
        choices=[('android', 'Android'), ('ios', 'iOS')],
        help_text="プラットフォーム"
    )
    build_number = serializers.CharField(max_length=20, required=False, help_text="ビルド番号")


class AppVersionResponseSerializer(serializers.Serializer):
    """アプリバージョンチェックレスポンス用シリアライザー"""
    
    latest_version = serializers.CharField(help_text="最新バージョン")
    update_required = serializers.BooleanField(help_text="強制更新が必要かどうか")
    update_available = serializers.BooleanField(help_text="更新が利用可能かどうか")
    update_message = serializers.CharField(help_text="更新メッセージ")
    download_url = serializers.URLField(help_text="ダウンロードURL")
    release_date = serializers.DateTimeField(help_text="リリース日時")


class UploadedImageSerializer(serializers.ModelSerializer):
    """画像アップロード情報シリアライザー"""
    
    file_size_mb = serializers.ReadOnlyField()
    
    class Meta:
        model = UploadedImage
        fields = [
            'id', 'original_filename', 'server_filename', 'file_url', 
            'file_size', 'file_size_mb', 'mime_type', 'event_code', 
            'team_name', 'cp_number', 'upload_source', 'device_platform',
            'capture_timestamp', 'upload_timestamp', 'device_info',
            'processing_status', 'thumbnail_url', 'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'server_filename', 'file_url', 'upload_timestamp', 'created_at', 'updated_at']


class MultiImageUploadSerializer(serializers.Serializer):
    """マルチ画像アップロード用シリアライザー"""
    
    event_code = serializers.CharField(max_length=50)
    team_name = serializers.CharField(max_length=255)
    cp_number = serializers.IntegerField()
    images = serializers.ListField(
        child=serializers.DictField(),
        max_length=10,  # 最大10ファイル
        help_text="アップロードする画像情報のリスト"
    )
    upload_source = serializers.ChoiceField(
        choices=['direct', 'sharing_intent', 'bulk_upload'],
        default='direct'
    )
    device_platform = serializers.ChoiceField(
        choices=['ios', 'android', 'web'],
        required=False
    )
    
    def validate_images(self, value):
        """画像データの検証"""
        if not value:
            raise serializers.ValidationError("画像が指定されていません")
        
        total_size = 0
        for image_data in value:
            # 必須フィールドチェック
            required_fields = ['file_data', 'filename', 'mime_type', 'file_size']
            for field in required_fields:
                if field not in image_data:
                    raise serializers.ValidationError(f"画像データに{field}が含まれていません")
            
            # ファイルサイズチェック
            file_size = image_data.get('file_size', 0)
            if file_size > 10485760:  # 10MB
                raise serializers.ValidationError(f"ファイル{image_data['filename']}のサイズが10MBを超えています")
            
            total_size += file_size
            
            # MIMEタイプチェック
            allowed_types = ['image/jpeg', 'image/png', 'image/heic', 'image/webp']
            if image_data.get('mime_type') not in allowed_types:
                raise serializers.ValidationError(f"サポートされていないファイル形式: {image_data.get('mime_type')}")
        
        # 合計サイズチェック（50MB）
        if total_size > 52428800:
            raise serializers.ValidationError("合計ファイルサイズが50MBを超えています")
        
        return value


class MultiImageUploadResponseSerializer(serializers.Serializer):
    """マルチ画像アップロードレスポンス用シリアライザー"""
    
    status = serializers.CharField()
    uploaded_count = serializers.IntegerField()
    failed_count = serializers.IntegerField()
    uploaded_files = serializers.ListField(
        child=serializers.DictField()
    )
    total_upload_size = serializers.IntegerField()
    processing_time_ms = serializers.IntegerField()
