from typing import List, Optional, Dict, Any from pydantic import BaseModel, Field from datetime import datetime from enum import Enum # Authentication Models class UserRole(str, Enum): """User roles enum.""" USER = "user" ADMIN = "admin" RESEARCHER = "researcher" class User(BaseModel): """User model for authentication.""" id: Optional[str] = Field(default=None, description="User ID from Supabase") email: str = Field(description="User email address") username: Optional[str] = Field(default=None, description="Username") full_name: Optional[str] = Field(default=None, description="Full name") role: UserRole = Field(default=UserRole.USER, description="User role") is_active: bool = Field(default=True, description="Whether user is active") created_at: Optional[datetime] = Field(default=None, description="Account creation timestamp") last_login: Optional[datetime] = Field(default=None, description="Last login timestamp") class UserSession(BaseModel): """User session model.""" id: Optional[str] = Field(default=None, description="Session ID") user_id: str = Field(description="User ID") access_token: str = Field(description="JWT access token") refresh_token: Optional[str] = Field(default=None, description="JWT refresh token") expires_at: datetime = Field(description="Token expiration time") created_at: Optional[datetime] = Field(default=None, description="Session creation time") last_used: Optional[datetime] = Field(default=None, description="Last used timestamp") user_agent: Optional[str] = Field(default=None, description="User agent string") ip_address: Optional[str] = Field(default=None, description="Client IP address") class LoginRequest(BaseModel): """Login request model.""" email: str = Field(description="User email") password: str = Field(description="User password", min_length=6) class RegisterRequest(BaseModel): """Registration request model.""" email: str = Field(description="User email") password: str = Field(description="User password", min_length=6) username: Optional[str] = Field(default=None, description="Username") full_name: Optional[str] = Field(default=None, description="Full name") class AuthResponse(BaseModel): """Authentication response model.""" access_token: str = Field(description="JWT access token") refresh_token: Optional[str] = Field(default=None, description="JWT refresh token") token_type: str = Field(default="bearer", description="Token type") expires_in: int = Field(description="Token expiration time in seconds") user: User = Field(description="User information") class TokenRefreshRequest(BaseModel): """Token refresh request model.""" refresh_token: str = Field(description="Refresh token") # Database Storage Models class NarratorExtractionRecord(BaseModel): """Database record for narrator extraction.""" id: Optional[str] = Field(default=None, description="Record ID") user_id: str = Field(description="User who made the request") hadith_text: str = Field(description="Original hadith text") extracted_narrators: List[str] = Field(description="Extracted narrator names") sanad_chain: str = Field(description="Extracted sanad chain") success: bool = Field(description="Whether extraction was successful") error_message: Optional[str] = Field(default=None, description="Error message if failed") processing_time_ms: Optional[int] = Field(default=None, description="Processing time in milliseconds") created_at: Optional[datetime] = Field(default=None, description="Creation timestamp") session_id: Optional[str] = Field(default=None, description="Session ID") ip_address: Optional[str] = Field(default=None, description="Client IP address") class NarratorAnalysisRecord(BaseModel): """Database record for narrator analysis.""" id: Optional[str] = Field(default=None, description="Record ID") user_id: str = Field(description="User who made the request") extraction_id: Optional[str] = Field(default=None, description="Related extraction record ID") narrator_name: str = Field(description="Analyzed narrator name") reliability_grade: str = Field(description="Assigned reliability grade") confidence_level: str = Field(description="Confidence level") reasoning: str = Field(description="Analysis reasoning") scholarly_consensus: str = Field(description="Scholarly consensus analysis") known_issues: Optional[str] = Field(default=None, description="Known issues") biographical_info: str = Field(description="Biographical information") recommendation: str = Field(description="Usage recommendation") success: bool = Field(description="Whether analysis was successful") error_message: Optional[str] = Field(default=None, description="Error message if failed") processing_time_ms: Optional[int] = Field(default=None, description="Processing time in milliseconds") created_at: Optional[datetime] = Field(default=None, description="Creation timestamp") # Existing Models (keeping them for compatibility) class NarratorGrade(BaseModel): """Grade for individual narrator in the chain.""" name: str = Field(description="Name of the narrator") reliability_grade: str = Field(description="Reliability grade: Thiqah (Trustworthy), Saduq (Truthful), Da'if (Weak), Matruk (Abandoned), or Majhul (Unknown)") reasoning: str = Field(description="Brief explanation for the narrator's grade") known_issues: Optional[str] = Field(default=None, description="Any known issues with this narrator") class HadithAnalysis(BaseModel): """Comprehensive hadith analysis with structured output.""" overall_grade: str = Field(description="Overall hadith grade: Sahih, Hasan, Da'if, or Mawdu'") confidence_level: str = Field(description="Confidence in the grading: High, Medium, or Low") # Sanad Analysis sanad_grade: str = Field(description="Grade of the chain of narration") narrator_grades: List[NarratorGrade] = Field(description="Individual grades for each narrator in the chain") chain_continuity: str = Field(description="Assessment of chain continuity: Connected, Broken, or Unclear") # Matn Analysis matn_grade: str = Field(description="Grade of the hadith text content") content_consistency: str = Field(description="Consistency with Quran and other authentic hadiths") language_authenticity: str = Field(description="Authenticity of the prophetic speech style") # Supporting Information primary_sources: List[str] = Field(description="Classical hadith collections where this hadith appears") scholarly_opinions: List[str] = Field(description="Opinions of classical and contemporary scholars") # Final Assessment detailed_reasoning: str = Field(description="Comprehensive explanation of the grading decision") practical_guidance: str = Field(description="Guidance for Muslims regarding acting upon this hadith") academic_notes: Optional[str] = Field(default=None, description="Additional scholarly observations") class HadithTextRequest(BaseModel): """Request model for hadith text analysis.""" hadith_text: str = Field(description="The complete hadith text in Arabic", min_length=1) class NarratorExtractionResponse(BaseModel): """Response model for narrator extraction.""" narrators: List[str] = Field(description="List of narrator names extracted from the hadith") sanad_chain: str = Field(description="The complete chain of narration (sanad)") success: bool = Field(description="Whether the extraction was successful") message: str = Field(description="Status message or error description") class ScholarlyOpinion(BaseModel): """Model for scholarly opinion on a narrator.""" scholar_name: str = Field(description="Name of the scholar") opinion: str = Field(description="The scholar's opinion or assessment") source: Optional[str] = Field(default=None, description="Source of the opinion") reliability_assessment: Optional[str] = Field(default=None, description="Reliability grade given by this scholar") class NarratorAnalysisRequest(BaseModel): """Request model for narrator analysis.""" narrator_name: str = Field(description="Name of the narrator to analyze", min_length=1) class NarratorAnalysisResponse(BaseModel): """Response model for narrator analysis.""" narrator_name: str = Field(description="Name of the analyzed narrator") reliability_grade: str = Field(description="Final reliability grade: Thiqah (Trustworthy), Saduq (Truthful), Da'if (Weak), Matruk (Abandoned), or Majhul (Unknown)") confidence_level: str = Field(description="Confidence in the assessment: High, Medium, Low") reasoning: str = Field(description="Detailed reasoning for the grade") scholarly_consensus: str = Field(description="Analysis of what scholars have said about this narrator") known_issues: Optional[str] = Field(default=None, description="Any known issues or criticisms of this narrator") biographical_info: str = Field(description="Basic biographical information about the narrator") recommendation: str = Field(description="Recommendation for using this narrator's narrations") success: bool = Field(description="Whether the analysis was successful") message: str = Field(description="Status message or error description") class IndividualNarratorAnalysis(BaseModel): """Individual narrator analysis within a chain.""" narrator_name: str = Field(description="Name of the analyzed narrator") reliability_grade: str = Field(description="Final reliability grade") confidence_level: str = Field(description="Confidence in the assessment: High, Medium, Low") reasoning: str = Field(description="Detailed reasoning for the grade") scholarly_consensus: str = Field(description="Analysis of scholarly opinions") known_issues: Optional[str] = Field(default=None, description="Any known issues or criticisms") biographical_info: str = Field(description="Basic biographical information") recommendation: str = Field(description="Recommendation for using this narrator's narrations") success: bool = Field(description="Whether the analysis was successful") message: str = Field(description="Status message or error description") class ChainAnalysisMetadata(BaseModel): """Metadata for chain analysis.""" total_narrators: int = Field(description="Total number of narrators in the chain") successful_analyses: int = Field(description="Number of successfully analyzed narrators") analysis_method: str = Field(description="Method used for analysis") class NarratorChainAnalysisResponse(BaseModel): """Response model for narrator chain analysis.""" chain: List[str] = Field(description="List of narrator names in the chain") individual_analyses: Dict[str, IndividualNarratorAnalysis] = Field(description="Individual analysis for each narrator") chain_synthesis: Dict[str, Any] = Field(description="Synthesized analysis of the complete chain") metadata: ChainAnalysisMetadata = Field(description="Analysis metadata") class ExtractionResult(BaseModel): """Extraction result sub-model.""" narrators: List[str] = Field(description="List of extracted narrator names") sanad_chain: str = Field(description="The complete chain of narration") success: bool = Field(description="Whether extraction was successful") message: str = Field(description="Status message or error description") class ChainAnalysisResult(BaseModel): """Chain analysis result sub-model.""" individual_analyses: Dict[str, IndividualNarratorAnalysis] = Field(description="Individual narrator analyses") synthesis: Dict[str, Any] = Field(description="Synthesized chain analysis") class ExtractAndAnalyzeMetadata(BaseModel): """Metadata for extract and analyze workflow.""" hadith_text_length: int = Field(description="Length of the input hadith text") extracted_narrators_count: int = Field(description="Number of extracted narrators") successful_analyses: int = Field(description="Number of successfully analyzed narrators") analysis_method: str = Field(description="Method used for analysis") class ExtractAndAnalyzeResponse(BaseModel): """Response model for extract and analyze workflow.""" extraction: ExtractionResult = Field(description="Results of narrator extraction") chain_analysis: Optional[ChainAnalysisResult] = Field(default=None, description="Results of chain analysis") metadata: ExtractAndAnalyzeMetadata = Field(description="Analysis metadata") error: Optional[str] = Field(default=None, description="Error message if analysis failed")