from typing import Annotated, Literal, Union

from pydantic import BaseModel, Field

from milky_types.message import IncomingMessage
from milky_types.scalar import t_bool, t_int32, t_int64, t_object, t_str

__all__ = [
	'BotOfflineData',
	'MessageRecallEventData',
	'FriendRequestEventData',
	'GroupJoinRequestEventData',
	'GroupInvitedJoinRequestEventData',
	'GroupInvitationEventData',
	'FriendNudgeEventData',
	'FriendFileUploadEventData',
	'GroupAdminChangeEventData',
	'GroupEssenceMessageChangeEventData',
	'GroupMemberIncreaseEventData',
	'GroupMemberDecreaseEventData',
	'GroupNameChangeEventData',
	'GroupMessageReactionEventData',
	'GroupMuteEventData',
	'GroupWholeMuteEventData',
	'GroupNudgeEventData',
	'GroupFileUploadEventData',
	'EventBase',
	'BotOfflineEvent',
	'MessageReceiveEvent',
	'MessageRecallEvent',
	'FriendRequestEvent',
	'GroupJoinRequestEvent',
	'GroupInvitedJoinRequestEvent',
	'GroupInvitationEvent',
	'FriendNudgeEvent',
	'FriendFileUploadEvent',
	'GroupAdminChangeEvent',
	'GroupEssenceMessageChangeEvent',
	'GroupMemberIncreaseEvent',
	'GroupMemberDecreaseEvent',
	'GroupNameChangeEvent',
	'GroupMessageReactionEvent',
	'GroupMuteEvent',
	'GroupWholeMuteEvent',
	'GroupNudgeEvent',
	'GroupFileUploadEvent',
	'Event',
]


class BotOfflineData(BaseModel):
	reason: str = t_str('下线原因')


class MessageRecallEventData(BaseModel):
	message_scene: Literal['friend', 'group', 'temp'] = t_str('消息场景')
	peer_id: int = t_int64('好友 QQ 号或群号')
	message_seq: int = t_int64('消息序列号')
	sender_id: int = t_int64('被撤回的消息的发送者 QQ 号')
	operator_id: int = t_int64('操作者 QQ 号')
	display_suffix: str = t_str('撤回提示的后缀文本')


class FriendRequestEventData(BaseModel):
	initiator_id: int = t_int64('申请好友的用户 QQ 号')
	initiator_uid: str = t_str('用户 UID')
	comment: str = t_str('申请附加信息')
	via: str = t_str('申请来源')


class GroupJoinRequestEventData(BaseModel):
	group_id: int = t_int64('群号')
	notification_seq: int = t_int64('请求对应的通知序列号')
	is_filtered: bool = t_bool('请求是否被过滤（发起自风险账户）')
	initiator_id: int = t_int64('申请入群的用户 QQ 号')
	comment: str = t_str('申请附加信息')


class GroupInvitedJoinRequestEventData(BaseModel):
	group_id: int = t_int64('群号')
	notification_seq: int = t_int64('请求对应的通知序列号')
	initiator_id: int = t_int64('邀请者 QQ 号')
	target_user_id: int = t_int64('被邀请者 QQ 号')


class GroupInvitationEventData(BaseModel):
	group_id: int = t_int64('群号')
	invitation_seq: int = t_int64('邀请序列号')
	initiator_id: int = t_int64('邀请者 QQ 号')


class FriendNudgeEventData(BaseModel):
	user_id: int = t_int64('好友 QQ 号')
	is_self_send: bool = t_bool('是否是自己发送的戳一戳')
	is_self_receive: bool = t_bool('是否是自己接收的戳一戳')
	display_action: str = t_str('戳一戳提示的动作文本')
	display_suffix: str = t_str('戳一戳提示的后缀文本')
	display_action_img_url: str = t_str('戳一戳提示的动作图片 URL')


class FriendFileUploadEventData(BaseModel):
	user_id: int = t_int64('好友 QQ 号')
	file_id: str = t_str('文件 ID')
	file_name: str = t_str('文件名称')
	file_size: int = t_int64('文件大小（字节）')
	file_hash: str = t_str('文件的 TriSHA1 哈希值')
	is_self: bool = t_bool('是否是自己发送的文件')


class GroupAdminChangeEventData(BaseModel):
	group_id: int = t_int64('群号')
	user_id: int = t_int64('发生变更的用户 QQ 号')
	operator_id: int = t_int64('操作者 QQ 号')
	is_set: bool = t_bool('是否被设置为管理员')


class GroupEssenceMessageChangeEventData(BaseModel):
	group_id: int = t_int64('群号')
	message_seq: int = t_int64('发生变更的消息序列号')
	operator_id: int = t_int64('操作者 QQ 号')
	is_set: bool = t_bool('是否被设置为精华')


class GroupMemberIncreaseEventData(BaseModel):
	group_id: int = t_int64('群号')
	user_id: int = t_int64('发生变更的用户 QQ 号')
	operator_id: int | None = t_int64('管理员 QQ 号', default=None)
	invitor_id: int | None = t_int64('邀请者 QQ 号', default=None)


class GroupMemberDecreaseEventData(BaseModel):
	group_id: int = t_int64('群号')
	user_id: int = t_int64('发生变更的用户 QQ 号')
	operator_id: int | None = t_int64('管理员 QQ 号', default=None)


class GroupNameChangeEventData(BaseModel):
	group_id: int = t_int64('群号')
	new_group_name: str = t_str('新的群名称')
	operator_id: int = t_int64('操作者 QQ 号')


class GroupMessageReactionEventData(BaseModel):
	group_id: int = t_int64('群号')
	user_id: int = t_int64('发送回应者 QQ 号')
	message_seq: int = t_int64('消息序列号')
	face_id: str = t_str('表情 ID')
	is_add: bool = t_bool('是否为添加')


class GroupMuteEventData(BaseModel):
	group_id: int = t_int64('群号')
	user_id: int = t_int64('发生变更的用户 QQ 号')
	operator_id: int = t_int64('操作者 QQ 号')
	duration: int = t_int32('禁言时长（秒）')


class GroupWholeMuteEventData(BaseModel):
	group_id: int = t_int64('群号')
	operator_id: int = t_int64('操作者 QQ 号')
	is_mute: bool = t_bool('是否全员禁言')


class GroupNudgeEventData(BaseModel):
	group_id: int = t_int64('群号')
	sender_id: int = t_int64('发送者 QQ 号')
	receiver_id: int = t_int64('接收者 QQ 号')
	display_action: str = t_str('戳一戳提示的动作文本')
	display_suffix: str = t_str('戳一戳提示的后缀文本')
	display_action_img_url: str = t_str('戳一戳提示的动作图片 URL')


class GroupFileUploadEventData(BaseModel):
	group_id: int = t_int64('群号')
	user_id: int = t_int64('发送者 QQ 号')
	file_id: str = t_str('文件 ID')
	file_name: str = t_str('文件名称')
	file_size: int = t_int64('文件大小（字节）')


class EventBase(BaseModel):
	time: int = t_int64('事件 Unix 时间戳（秒）')
	self_id: int = t_int64('机器人 QQ 号')


class BotOfflineEvent(EventBase):
	event_type: Literal['bot_offline'] = t_str('机器人离线事件')
	data: BotOfflineData = t_object('下线原因')


class MessageReceiveEvent(EventBase):
	event_type: Literal['message_receive'] = t_str('消息接收事件')
	data: IncomingMessage = t_object('接收消息')


class MessageRecallEvent(EventBase):
	event_type: Literal['message_recall'] = t_str('消息撤回事件')
	data: MessageRecallEventData = t_object('撤回信息')


class FriendRequestEvent(EventBase):
	event_type: Literal['friend_request'] = t_str('好友请求事件')
	data: FriendRequestEventData = t_object('请求信息')


class GroupJoinRequestEvent(EventBase):
	event_type: Literal['group_join_request'] = t_str('入群请求事件')
	data: GroupJoinRequestEventData = t_object('请求信息')


class GroupInvitedJoinRequestEvent(EventBase):
	event_type: Literal['group_invited_join_request'] = t_str(
		'群成员邀请他人入群请求事件'
	)
	data: GroupInvitedJoinRequestEventData = t_object('请求信息')


class GroupInvitationEvent(EventBase):
	event_type: Literal['group_invitation'] = t_str('他人邀请自身入群事件')
	data: GroupInvitationEventData = t_object('邀请信息')


class FriendNudgeEvent(EventBase):
	event_type: Literal['friend_nudge'] = t_str('好友戳一戳事件')
	data: FriendNudgeEventData = t_object('戳一戳信息')


class FriendFileUploadEvent(EventBase):
	event_type: Literal['friend_file_upload'] = t_str('好友文件上传事件')
	data: FriendFileUploadEventData = t_object('文件信息')


class GroupAdminChangeEvent(EventBase):
	event_type: Literal['group_admin_change'] = t_str('群管理员变更事件')
	data: GroupAdminChangeEventData = t_object('变更信息')


class GroupEssenceMessageChangeEvent(EventBase):
	event_type: Literal['group_essence_message_change'] = t_str('群精华消息变更事件')
	data: GroupEssenceMessageChangeEventData = t_object('变更信息')


class GroupMemberIncreaseEvent(EventBase):
	event_type: Literal['group_member_increase'] = t_str('群成员增加事件')
	data: GroupMemberIncreaseEventData = t_object('增加信息')


class GroupMemberDecreaseEvent(EventBase):
	event_type: Literal['group_member_decrease'] = t_str('群成员减少事件')
	data: GroupMemberDecreaseEventData = t_object('减少信息')


class GroupNameChangeEvent(EventBase):
	event_type: Literal['group_name_change'] = t_str('群名称变更事件')
	data: GroupNameChangeEventData = t_object('变更信息')


class GroupMessageReactionEvent(EventBase):
	event_type: Literal['group_message_reaction'] = t_str('群消息表情回应事件')
	data: GroupMessageReactionEventData = t_object('回应信息')


class GroupMuteEvent(EventBase):
	event_type: Literal['group_mute'] = t_str('群禁言事件')
	data: GroupMuteEventData = t_object('禁言信息')


class GroupWholeMuteEvent(EventBase):
	event_type: Literal['group_whole_mute'] = t_str('群全体禁言事件')
	data: GroupWholeMuteEventData = t_object('禁言信息')


class GroupNudgeEvent(EventBase):
	event_type: Literal['group_nudge'] = t_str('群戳一戳事件')
	data: GroupNudgeEventData = t_object('戳一戳信息')


class GroupFileUploadEvent(EventBase):
	event_type: Literal['group_file_upload'] = t_str('群文件上传事件')
	data: GroupFileUploadEventData = t_object('文件信息')


Event = Annotated[
	Union[
		BotOfflineEvent,
		MessageReceiveEvent,
		MessageRecallEvent,
		FriendRequestEvent,
		GroupJoinRequestEvent,
		GroupInvitedJoinRequestEvent,
		GroupInvitationEvent,
		FriendNudgeEvent,
		FriendFileUploadEvent,
		GroupAdminChangeEvent,
		GroupEssenceMessageChangeEvent,
		GroupMemberIncreaseEvent,
		GroupMemberDecreaseEvent,
		GroupNameChangeEvent,
		GroupMessageReactionEvent,
		GroupMuteEvent,
		GroupWholeMuteEvent,
		GroupNudgeEvent,
		GroupFileUploadEvent,
	],
	Field(discriminator='event_type', description='事件'),
]
