"""
Auto-generated Pydantic models for BlackBox Schemas
Compatible with Pydantic v2.x
"""

from typing import Dict, List, Optional, Any, Union
from pydantic import BaseModel, Field, ConfigDict, field_validator, model_validator
from enum import Enum
import re


# Models from package/schema.py
from datetime import datetime
class CategoryEvaluation(BaseModel):
    category: str  = Field(description="The category name being evaluated")
    pros_cons: dict[str, list[str]]  = Field(
        description="Dictionary containing 'Pros' and 'Cons' keys, each with a list of points. Example: {'Pros':['pro1', 'pro 2', .... ], 'Cons':['Con 1', 'Con 2', ....]},",
        example={
            "Pros": ["pro1", "pro2", "pro3", "pro4"],
            "Cons": ["con1", "con2", "con3", "con4"],
        },
    )
    feasibility: str  = Field(description="Yes/No/moderate assessment of feasibility")
    observations: List[str]  = Field(
        description="List of observations for this category"
    )
    recommendations: List[str]  = Field(
        description="List of recommendations for this category"
    )



class Recommendation(BaseModel):
    decision: str  = Field(description="Go/No-Go decision/Moderate")
    summary: str  = Field(description="Summary of key factors influencing the decision")
    next_steps: List[str]  = Field(description="List of suggested next steps")



class SubmissionDetails(BaseModel):
    due_date: str  = Field(
        description="Exact submission deadline from RFP in YYYY-MM-DD format. Look for phrases like 'proposals due', 'submission deadline', 'closing date', or 'must be received by'."
    )
    submission_type: str  = Field(
        description="Type of submission method: 'online' (email, web portal, digital upload) or 'offline' (physical delivery, mail, in-person)"
    )
    submission_details: str  = Field(
        description="Specific submission location and method: email address, web portal URL, physical mailing address, or office location where proposals must be submitted"
    )
    submission_instructions: str  = Field(
        description="Detailed instructions for proposal preparation and submission: required format (PDF, hard copy), number of copies, file size limits, naming conventions, required sections, and any special submission requirements"
    )



class RFPEvaluation(BaseModel):
    evaluation: List[CategoryEvaluation]  = Field(
        description="List of category evaluations"
    )
    recommendation: Recommendation  = Field(description="Final recommendation")
    timeline_and_submission_details: SubmissionDetails  = Field(
        description="Timeline and submission details",
        alias="timeline_and_submission_details",
    )

    model_config = ConfigDict()


class LegalAdministrativeRequirements(BaseModel):
    insurance_requirements: Optional[str]
    company_info_requirements: Optional[str]
    certification_requirements: Optional[str]
    subcontracting_requirements: Optional[str]
    required_forms_and_attachments: Optional[str]
    other_admin_requirements: Optional[str]



class TechnicalOperationalRequirements(BaseModel):
    client_background: Optional[str]
    project_purpose_objectives: Optional[str]
    qualification_requirements: Optional[str]
    scope_of_work: Optional[str]
    deliverables: Optional[str]
    timeline_and_milestones: Optional[str]
    proposal_format: Optional[str]
    evaluation_criteria: Optional[str]
    budget_guidelines: Optional[str]
    location_requirements: Optional[str]
    technical_specifications: Optional[str]



class GuidanceAndClarifications(BaseModel):
    ambiguous_requirements: Optional[List[str]]  = Field(default_factory=list)
    implicit_requirements: Optional[List[str]]  = Field(default_factory=list)
    clarification_needed: Optional[List[str]]  = Field(default_factory=list)



class PageReferences(BaseModel):
    section_to_page: Optional[Dict[str, str]]  = Field(
        default_factory=dict, description="e.g., {'Scope of Work': 'Pg 6–8'}"
    )



class RFPAnalysisOutput(BaseModel):
    legal_admin_requirements: LegalAdministrativeRequirements
    technical_requirements: TechnicalOperationalRequirements
    guidance_notes: GuidanceAndClarifications
    page_references: Optional[PageReferences] = None
    rfp_metadata: Optional[Dict[str, str]]  = Field(
        default_factory=dict,
        description="Optional metadata like client name, issue date",
    )



class UserPreferencesSection(BaseModel):
    question: str  = Field(
        ..., description="The question to be answered by the content generator"
    )
    suggested_answer: str  = Field(
        ..., description="The suggested answer to the question"
    )



class UserPreferences(BaseModel):
    user_preferences: List[UserPreferencesSection]  = Field(...)



class TOCSubSection(BaseModel):
    subSectionNumber: str  = Field(..., description="The subsection number (e.g. '2.1')")
    subSectionTitle: str  = Field(..., description="The subsection title")



class TOCSection(BaseModel):
    sectionNumber: str  = Field(..., description="Section number (e.g. '2')")
    sectionTitle: str  = Field(..., description="Section title")
    subSections: List[TOCSubSection]  = Field(default_factory=list)
    agentSpecialisation: str  = Field(
        ..., description="Which agent handles this section"
    )
    specificInstruction: str  = Field(
        default="", description="Any special instructions for this section"
    )
    relevant_sections: List[str]  = Field(
        default_factory=list,
        description="List of RFP headings relevant to this section",
    )
    prompt: str  = Field(..., description="The meta-prompt for the content generator")



class TableOfContents(BaseModel):
    outline_json: List[TOCSection]  = Field(...)
    exec_summary_section_number: Optional[int]  = Field(
        ..., description="Section number for the executive summary"
    )



class RfpSection(BaseModel):
    heading: str  = Field(..., description="Most relevant name for this section")
    content: str  = Field(..., description="Actual content of the section")



class RfpSummary(BaseModel):
    rfp_sections: List[RfpSection]  = Field(
        ..., description="List of sections in the RFP"
    )



class RfpCompanyDataSection(BaseModel):
    heading: str  = Field(description="Most relevant name for this section")
    content: str  = Field(description="Actual content of the section")



class RfpCompanyData(BaseModel):
    rfp_sections: List[RfpCompanyDataSection]  = Field(
        description="List of sections in the RFP"
    )
    summary: str  = Field(description="Overall summary of the RFP document")



class PromptSubSection(BaseModel):
    """Subsection within a proposal section."""

    subSectionNumber: str  = Field(
        ..., description="The subsection number (e.g., '2.1')"
    )
    subSectionTitle: str  = Field(..., description="The title of the subsection")



class PromptSection(BaseModel):
    """Section within a proposal table of contents."""

    sectionNumber: str  = Field(..., description="The section number (e.g., '2')")
    sectionTitle: str  = Field(..., description="The title of the section")
    subSections: List[PromptSubSection]  = Field(
        default_factory=list, description="List of subsections within this section"
    )
    agentSpecialisation: str  = Field(
        ..., description="The type of agent specialized for this section"
    )
    specificInstruction: str  = Field(
        default="",
        description="Any particular instructions or guidelines relevant to this section",
    )
    relevant_sections: List[str]  = Field(
        default_factory=list, description="List of relevant sections for this section"
    )
    relevant_deep_research_sections: List[str]  = Field(
        default_factory=list,
        description="List of relevant deep research sections for this section",
    )
    prompt: str  = Field(..., description="This stores the prompt for this section")



class ContentGenerationSubsection(BaseModel):
    """Content for a subsection within a proposal section."""

    subsectionName: str  = Field(..., description="The name of the subsection")
    content: str  = Field(..., description="The content for this subsection")



class ContentGenerationSection(BaseModel):
    """Content for a section within a proposal document."""

    sectionName: str  = Field(..., description="The name of the section")
    content: str  = Field(..., description="The main content for this section")
    subsections: List[ContentGenerationSubsection]  = Field(
        default_factory=list,
        description="List of subsections within this section",
    )



class CostFormatingSections(BaseModel):
    sections: List[ContentGenerationSection]  = Field(
        ..., description="Contain all Sections"
    )



class CostSummarySection(BaseModel):
    heading: str  = Field(description="Most relevant name for this section")
    content: str  = Field(description="Actual content of the section")
    state: str  = Field(description="exact state name")
    county_town_name: str  = Field(description="exact official name")



class License(BaseModel):
    license_name: str  = Field(description="License name present in rfp proposal")
    license_total_cost: int  = Field(description="Actual price or estimated price")
    license_duration: str  = Field(description="annual or monthly duration of license")
    # license_description: str  = Field(description="Description of the license")
    license_quantity: int  = Field(description="number of licenses required")
    license_scope: str  = Field(description="scope of license")
    license_minimum_purchase_requirements: str  = Field(
        description="minimum purchase requirements"
    )
    license_source_reference: str  = Field(
        description="source reference of license in url formate"
    )
    license_discount: str  = Field(
        description="discount if any related to partner or vendor"
    )



class LicenseList(BaseModel):
    licenses: List[License]  = Field(
        description="List of licenses found in the RFP proposal"
    )



class CostSubSection(BaseModel):
    job_title: str  = Field(..., description="job title according to rfp proposal")
    hours: int  = Field(..., description="exact number of hours according to job title")
    description: str  = Field(..., description="The subsection content")



class JobTitle(BaseModel):
    old_job_title: str  = Field(..., description="Job title inside proposal")
    new_job_title: str  = Field(
        ..., description="exact number of hours according to job title"
    )
    Experience_level: str  = Field(..., description="Experience level")
    hours: int  = Field(..., description="exact number of hours according to job title")
    description: str  = Field(..., description="The subsection content")



class CostSection(BaseModel):
    state: str  = Field(description="Exact state name")
    county_town_name: str  = Field(
        description="exact official name which match official U.S. Census Bureau or FIPS geographic entities"
    )
    job_title: List[JobTitle]  = Field(description="job title eplained in prompt")
    number_of_personnel: int  = Field(description="exact county of number of personnel")
    personnel_source_reference: str  = Field(
        description="source reference of personnel in url formate"
    )
    total_cost: str  = Field(
        description="total cost value with source reference (e.g., '$100,000 from RFP_SUMMARY' or '$150,000 from RFP_PROPOSAL' or 'No cost given in RFP')"
    )
    job_title_total_hours: int  = Field(description="only number")
    job_title_hours: List[CostSubSection]  = Field(
        description="job title hours explained in prompt"
    )
    cost_proposal: str  = Field(
        description="cost proposal in the format specified by the RFP else phase-wise cost estimation according to job title from Total hours, if it contain tables show them"
    )
    location_type: str  = Field(description="Location type")
    cost_field_name: List[str]  = Field(
        description="List of section names which contain cost"
    )



class InfrastructureItem(BaseModel):
    component: str  = Field(
        ..., description="Name of the infrastructure component or service"
    )
    requirement: str  = Field(
        ..., description="The explicit or inferred requirement from RFP"
    )
    fulfillment_strategy: str  = Field(
        ..., description="Best-practice strategy for meeting the requirement"
    )
    estimated_monthly_cost: float  = Field(
        ..., description="Estimated cost in USD per month"
    )
    estimated_annual_cost: float  = Field(
        ..., description="Estimated annual cost in USD"
    )
    notes: Optional[str]  = Field("", description="Assumptions or considerations")



class InfrastructureSummary(BaseModel):
    items: List[InfrastructureItem]  = Field(
        ..., description="List of infrastructure components and cost strategies"
    )
    total_monthly_cost: float  = Field(
        ..., description="Total estimated monthly cost for infrastructure"
    )
    total_annual_cost: float  = Field(
        ..., description="Total estimated annual cost for infrastructure"
    )
    additional_notes: Optional[str]  = Field(
        None, description="Optional compliance or pricing notes"
    )



class CostImageCalculationResult(BaseModel):
    table_result: str  = Field(
        ..., description="Generated cost table or explanation result"
    )



class HourlyJobTitleWages(BaseModel):
    old_job_title: str  = Field(description="List of job titles")
    Experience_level: str  = Field(description="List of experience levels")
    hours: int  = Field(description="List of hours for each job title")
    hourly_wage: float  = Field(description="List of hourly wages")
    description: str  = Field(
        ...,
        description="How you exactly calculated the number of hours for each job title",
    )



class HourlySection(BaseModel):
    hourly_job_title_wages: List[HourlyJobTitleWages]  = Field(
        description="List all the hourly job title wages"
    )


