from sqlalchemy import Boolean, Column, Integer, String, ForeignKey, DateTime, Date, Text, UniqueConstraint
from sqlalchemy.sql import func

from app.database import Base


class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    email = Column(String, unique=True)
    name = Column(String)
    access_token = Column(String)
    refresh_token = Column(String, nullable=True)
    role = Column(String, nullable=False, default="user", server_default="user")
    approval_status = Column(String, nullable=False, default="pending", server_default="pending")
    approved_at = Column(DateTime(timezone=True), nullable=True)
    approved_by = Column(Integer, ForeignKey("users.id"), nullable=True)
    denied_at = Column(DateTime(timezone=True), nullable=True)
    calendar_sync_enabled = Column(Boolean, nullable=False, default=False, server_default="false")


class Meeting(Base):
    __tablename__ = "meetings"

    id = Column(Integer, primary_key=True, index=True)
    title = Column(String, nullable=True)
    calendar_event_id = Column(String, nullable=True, index=True)
    meet_link = Column(String)
    platform = Column(String, default="google_meet")
    user_id = Column(Integer, ForeignKey("users.id"))
    scheduled_at = Column(DateTime(timezone=True), nullable=True)
    status = Column(String, default="pending")
    recall_bot_id = Column(String, nullable=True, unique=True)
    recall_join_at = Column(DateTime(timezone=True), nullable=True)
    provider = Column(String, default="recall_ai")
    bot_status = Column(String, nullable=True)
    bot_sub_code = Column(String, nullable=True)
    bot_payload = Column(Text, nullable=True)
    is_recurring = Column(Boolean, nullable=False, default=False, server_default="false")
    recurring_series_id = Column(String, nullable=True, index=True)
    source_event_id = Column(String, nullable=True, index=True)
    host_rsvp_status = Column(String, nullable=True)
    app_toggle_enabled = Column(Boolean, nullable=True)
    created_at = Column(Date, server_default=func.current_date())


class RecurringMeetingCandidate(Base):
    __tablename__ = "recurring_meeting_candidates"
    __table_args__ = (
        UniqueConstraint("user_id", "google_event_id", name="uq_recurring_candidate_user_event"),
    )

    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True)
    recurring_series_id = Column(String, nullable=False, index=True)
    google_event_id = Column(String, nullable=False, index=True)
    title = Column(String, nullable=True)
    meet_link = Column(String, nullable=False)
    platform = Column(String, nullable=False, default="google_meet")
    scheduled_at = Column(DateTime(timezone=True), nullable=False, index=True)
    host_rsvp_status = Column(String, nullable=True)
    organizer_email = Column(String, nullable=True)
    app_toggle_enabled = Column(Boolean, nullable=False, default=False, server_default="false")
    bot_permission_status = Column(String, nullable=False, default="pending", server_default="pending")
    dashboard_visible = Column(Boolean, nullable=False, default=False, server_default="false")
    linked_meeting_id = Column(Integer, ForeignKey("meetings.id"), nullable=True, unique=True)
    payload_json = Column(Text, nullable=True)
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())


class RecurringMeetingInvite(Base):
    __tablename__ = "recurring_meeting_invites"
    __table_args__ = (
        UniqueConstraint("guest_user_id", "google_event_id", name="uq_recurring_meeting_invite_guest_event"),
    )

    id = Column(Integer, primary_key=True, index=True)
    host_user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True)
    guest_user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
    meeting_id = Column(Integer, ForeignKey("meetings.id"), nullable=True, index=True)
    recurring_series_id = Column(String, nullable=False, index=True)
    google_event_id = Column(String, nullable=False, index=True)
    title = Column(String, nullable=True)
    meet_link = Column(String, nullable=False)
    platform = Column(String, nullable=False, default="google_meet")
    scheduled_at = Column(DateTime(timezone=True), nullable=False, index=True)
    guest_rsvp_status = Column(String, nullable=True)
    organizer_email = Column(String, nullable=True)
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())


class NonRecurringMeetingInvite(Base):
    __tablename__ = "non_recurring_meeting_invites"
    __table_args__ = (
        UniqueConstraint("guest_user_id", "google_event_id", name="uq_non_recurring_meeting_invite_guest_event"),
    )

    id = Column(Integer, primary_key=True, index=True)
    host_user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True)
    guest_user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True)
    meeting_id = Column(Integer, ForeignKey("meetings.id"), nullable=True, index=True)
    google_event_id = Column(String, nullable=False, index=True)
    title = Column(String, nullable=True)
    meet_link = Column(String, nullable=False)
    platform = Column(String, nullable=False, default="google_meet")
    scheduled_at = Column(DateTime(timezone=True), nullable=False, index=True)
    guest_rsvp_status = Column(String, nullable=True)
    organizer_email = Column(String, nullable=True)
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())


class Recording(Base):
    __tablename__ = "recordings"

    id = Column(Integer, primary_key=True, index=True)
    meeting_id = Column(Integer, ForeignKey("meetings.id"), unique=True)
    file_path = Column(String, nullable=True)
    status = Column(String, default="recording")
    recall_recording_id = Column(String, nullable=True, unique=True)
    audio_download_url = Column(Text, nullable=True)
    video_download_url = Column(Text, nullable=True)
    transcript_download_url = Column(Text, nullable=True)
    transcript_provider_data_download_url = Column(Text, nullable=True)
    participant_events_download_url = Column(Text, nullable=True)
    speaker_timeline_download_url = Column(Text, nullable=True)
    participants_download_url = Column(Text, nullable=True)
    recording_payload = Column(Text, nullable=True)
    is_media_expired = Column(Boolean, nullable=False, default=False, server_default="false")
    download_urls_refreshed_at = Column(DateTime(timezone=True), nullable=True)
    started_at = Column(DateTime(timezone=True), server_default=func.now())
    stopped_at = Column(DateTime(timezone=True), nullable=True)


class Transcript(Base):
    __tablename__ = "transcripts"

    id = Column(Integer, primary_key=True, index=True)
    meeting_id = Column(Integer, ForeignKey("meetings.id"), unique=True)
    recall_transcript_id = Column(String, nullable=True, unique=True)
    status = Column(String, default="pending")
    language = Column(String, nullable=True)
    duration_seconds = Column(Integer, nullable=True)
    participants = Column(String, nullable=True)
    speaker_map = Column(String, nullable=True)
    transcript_json = Column(String, nullable=True)
    full_text = Column(String, nullable=True)
    error_message = Column(String, nullable=True)
    download_url = Column(Text, nullable=True)
    provider_data_download_url = Column(Text, nullable=True)
    transcript_payload = Column(Text, nullable=True)
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    completed_at = Column(DateTime(timezone=True), nullable=True)


class RecallWebhookEvent(Base):
    __tablename__ = "recall_webhook_events"

    id = Column(Integer, primary_key=True, index=True)
    webhook_id = Column(String, unique=True, nullable=False, index=True)
    event = Column(String, nullable=False)
    bot_id = Column(String, nullable=True, index=True)
    recording_id = Column(String, nullable=True, index=True)
    transcript_id = Column(String, nullable=True, index=True)
    status_code = Column(String, nullable=True)
    status_sub_code = Column(String, nullable=True)
    payload = Column(Text, nullable=False)
    processed_at = Column(DateTime(timezone=True), nullable=True)
    processing_error = Column(Text, nullable=True)
    created_at = Column(DateTime(timezone=True), server_default=func.now())


class CalendarSyncState(Base):
    __tablename__ = "calendar_sync_states"

    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer, ForeignKey("users.id"), nullable=False, unique=True, index=True)
    calendar_id = Column(String, nullable=False, server_default="primary")
    sync_token = Column(Text, nullable=True)
    webhook_url = Column(Text, nullable=True)
    channel_id = Column(String, nullable=True, unique=True, index=True)
    channel_token = Column(String, nullable=True)
    resource_id = Column(String, nullable=True)
    resource_uri = Column(Text, nullable=True)
    expires_at = Column(DateTime(timezone=True), nullable=True)
    last_message_number = Column(String, nullable=True)
    last_synced_at = Column(DateTime(timezone=True), nullable=True)
    created_at = Column(DateTime(timezone=True), server_default=func.now())
