import subprocess
import time
from collections.abc import Callable
from contextlib import asynccontextmanager

from fastapi import FastAPI, HTTPException, Request, Response
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles
from sqlalchemy.exc import ProgrammingError
from fastapi import Depends
from fastapi.security import OAuth2PasswordBearer

#from app.api.auth.router import auth_router  # Import the authentication router
from app.api.user.router import user_router
from app.api.brand.router import brand_router
from app.api.segment.router import segment_router
from app.api.store_formate.router import store_formate_router
from app.api.student.router import student_router
from app.api.simulation.router import simulation_router
from app.api.group.router import group_router
from app.api.customer_location.router import customer_location_router
from app.api.catchment_potential.router import catchment_potential_router
from app.api.network.router import network_planning_router
from app.api.payment.router import payment_router
from app.api.excel_download.router import excel_router
from app.api.civil.router import civil_router
from app.api.display_racking_create.router import display_racking_unit_router
from app.api.commercial_equipment.router import commercial_equipment_router
from app.api.plumbing.router import plumbing_router
from app.api.trading_month.router import trading_month_router
from app.api.pre_operating_expenses.router import pre_operating_router
from app.api.competitor_analysis.router import competitor_analysis_router
from app.api.display_board.router import displayboard_router
from app.api.competitor_bench_marking.router import competitor_bench_marking_router
from app.api.carpentry.router import carpentry_router
from app.api.info_tech.router import info_tech_router
from app.api.visual_merchandising_elements.router import visual_merch_elements_router
from app.api.depreciation.router import  depreciation_router
from app.api.competitor_category_analyses.router import competitor_category_analyses_router
# from app.api.store_investment_summary.router import store_investment_summary_router
# from app.api.consumer_preferences_research.router import consumer_preferences_research_router
from app.api.pre_selected_category.router import pre_select_category_router
from app.api.gross_margin_contribution.router import gross_margin_contribution_router
from app.api.vendor_metrics_priority_list.router import vendor_metrics_priority_list_router
from app.api.vendor_scorecard.router import vendor_scorecard_router
from app.api.private_lablling.router import private_lablling_router
from app.api.category_captinship_planning.router import category_captinship_planning_router
from app.api.addtional_installation_fix.router import additional_installation_router
from app.api.sales_estimate.router import sales_estimate_router
from app.api.rent_expenses.router import rent_expenses_router
from app.api.competitor_pricing_analysis.router import competitor_pricing_analysis_router
from app.api.corporate_store.router import corporate_store_router
from app.api.category_definition_excel.router import category_definition_excel_router
from app.api.competitor_analysis_comparison.router import competitor_analysis_comparison_router
from app.api.corporate_concept_office.router import corporate_concept_office_router
from app.api.utilitys.router import utility_router
from app.api.operating_expenses.router import operating_expenses_router
from app.api.store_formate_pricing_strategies.router import store_formate_pricing_router
from app.api.store_level_staff_needs.router import store_level_staff_router
from app.api.centralised_and_direct.router import centralised_and_direct_router
from app.api.category_wish_inventory.router import category_wish_inventory_routre
from app.api.shrinkage_areas_reasons.router import shrinkage_areas_reasons_router
from app.api.inventory_excel.router import inventory_excel_router
from app.api.online_policies.router import online_policies_router
from app.api.sales.router import sales_router
from app.api.recurring_operating_expenses.router import recurring_operating_router
from app.api.digital_asset_acquisition.router import digital_asset_router
from app.api.marketing_competitor_analysis.router import marketing_competitor_router
from app.api.competitor_intensity.router import competitorintensity_router
from app.api.projected_market_share.router import projected_market_share_router
from app.api.location_spillage_factor_analysis.router import location_spillage_router
from app.api.location_details.router import location_details_router
from app.api.electrical_cabling.router import electrical_cabling_router
from app.api.category_pricing_strategis.router import category_pricing_strategis_router
from app.api.define_your_promotions_strategy.router import define_your_promotions_router
from app.api.promotion_competitor_analysis.router import promotion_competitor_analysis_router
from app.api.recovery_of_promotional.router import recovery_promotional_router
from app.api.customer_engagement_strategies.router import customer_engagement_router
from app.api.competitor_loyalty_program.router import competitor_loyalty_router
from app.api.brand_attribute_assessment.router import brand_attribute_assessment_router
from app.api.branding_attributes.router import branding_attributes_router
from app.api.integrated_marketing.router import integrated_marketing_router
from app.api.annexures.router import annexures_router
from app.api.optimising_assets_for_revenue.router import optimising_assets_router
from app.api.short_negotiation_final.router import short_negotiation_final_router
from app.api.margin_and_sales_contribution_analysis.router import margin_and_sales_contribution_analysis_router
from app.api.online_pre_selected_service_level.router import online_pre_select_service_router
from app.api.adapting_supply_chain.router import adapting_supply_chain_router
from app.api.critical_for_business.router import critical_for_business_router
from app.api.expanded_performance_metrics.router import expanded_performance_metrics_router
from app.api.categories_under_promotions.router import categories_under_promotions_router
from app.api.comparative_analysis.router import comparative_analysis_router
from app.api.measuring_sales_profitability.router import measuring_sales_profitability_router
from app.api.pre_selected_service.router import pre_selected_service_router
from app.api.concept_office.router import concept_office_router
from app.api.store_investment_summary.router import store_investment_summary_router
from app.api.summary.router import summary_router
from app.api.cash_conversion_cycle.router import cash_conversion_cycle_router
from app.api.visual_merchandising_strategy.router import visual_merch_Strategy_router
from app.api.student_excel.router import stu_router
from app.api.master.router import master_router
from app.api.user_simulation.router import user_simulation_router
from app.api.category_simulation.router import category_simulation_router
from app.api.physical_store_formats.router import physical_store_formats_router
from app.api.cap_ex_refurbish.router import cap_ex_refurbish_router
from app.api.online_store_format.router import online_store_format_router
from app.api.module_1.router import module_1_report_router
from app.api.module_2.router import module_2_report_router
from app.api.module_3.router import module_3_report_router
from app.api.module_4_report.router import module_4_report_router
from app.api.module_5_report.router import module_5_report_router
from app.api.module_6_report.router import module_6_report_router
from app.api.module_7_report.router import module_7_report_router
from app.api.module_8_report.router import module_8_report_router
from app.api.module_9_report.router import module_9_report_router
from app.api.module_10_report.router import module_10_report_router
from app.api.all_content.router import all_content_router
from app.api.promotion_calender.router import promotion_calender_router
from app.api.institution.router import institution_router
from app.config import settings  # Import configuration settings
from app.database.main.mongo import MongoDBSingleton

from sqlalchemy.exc import OperationalError
from app.exceptions import (
    handle_generic_exception_handler,
    handle_programming_error,
    http_exception_error_handler,
    handel_operational_error_handler,
    handel_attribute_error_handler
)
from app.utils.schemas_utils import CustomResponse

mongodb_instance = MongoDBSingleton()  # Initialize MongoDB singleton instance

@asynccontextmanager
async def lifespan(_app: FastAPI):
    """Initialize the application."""
    # Load the MongoDB instance
    _ = mongodb_instance

    yield  # Yield control back to the application

app = FastAPI(
    title=settings.PROJECT_NAME,
    version=settings.API_VERSION,
    description=settings.DESCRIPTION,
    # docs_url=None,  # Optionally disable the interactive API docs
    # redoc_url=None,  # Optionally disable the ReDoc docs
    lifespan=lifespan,  # Set the lifespan context manager
    debug=True,  # Enable debug mode
)

@app.middleware("http")
async def add_process_time_header(request: Request, call_next: Callable) -> Response:
    """
    Add process time header to the response.

    Args:
        request (Request): The incoming request.
        call_next (Callable): The next callable in the middleware chain.

    Returns:
        Response: The response with added process time header.
    """
    start_time = time.time()
    response = await call_next(request)  # Process the request
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)  # Add process time header to the response
    return response

# Add CORS middleware to the application
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # Allow all origins (set to a list of allowed origins for production)
    allow_credentials=True,
    allow_methods=["*"],  # Allow all HTTP methods
    allow_headers=["*"],  # Allow all HTTP headers
    expose_headers=["*"],  # Expose all headers
)

# Include the authentication router with prefix and tags
#app.include_router(auth_router, prefix="/FASTAPI", tags=["AUTH"])
app.include_router(user_router, prefix="/FASTAPI", tags=["User"])
app.include_router(brand_router, prefix="/FASTAPI", tags=["Brand"])
app.include_router(segment_router, prefix="/FASTAPI", tags=["Segment"])
app.include_router(store_formate_router, prefix="/FASTAPI", tags=["Store Formate"])
app.include_router(student_router, prefix="/FASTAPI", tags=["Student"])
app.include_router(simulation_router,prefix="/FASTAPI", tags=["Simulation"])
app.include_router(group_router,prefix="/FASTAPI", tags=["Group"])
app.include_router(customer_location_router,prefix="/FASTAPI", tags=["Customer Location"])
app.include_router(catchment_potential_router,prefix="/FASTAPI", tags=["Catchment Potential"])
app.include_router(network_planning_router,prefix="/FASTAPI", tags=["Network Planning"])
app.include_router(payment_router,prefix="/FASTAPI", tags=["Payment"])
app.include_router(excel_router,prefix="/FASTAPI", tags=["Download Excel"])
app.include_router(civil_router,prefix="/FASTAPI", tags=["Civil and Backroom Work"])
app.include_router(display_racking_unit_router,prefix="/FASTAPI", tags=["Display and Racking Units"])
app.include_router(commercial_equipment_router,prefix="/FASTAPI", tags=["Commercial Equipment"])
app.include_router(plumbing_router,prefix="/FASTAPI", tags=["Plumbing"])
app.include_router(trading_month_router,prefix="/FASTAPI", tags=["Trading Months"])
app.include_router(pre_operating_router,prefix="/FASTAPI", tags=["Pre-Operating Expenses"])
app.include_router(competitor_analysis_router,prefix="/FASTAPI", tags=["Competitor Analysis"])
app.include_router(displayboard_router,prefix="/FASTAPI", tags=["Display Board"])
app.include_router(competitor_bench_marking_router,prefix="/FASTAPI", tags=["Competitor Bench Marking"])
app.include_router(carpentry_router,prefix="/FASTAPI", tags=["Carpentry"])
app.include_router(info_tech_router,prefix="/FASTAPI", tags=["Info Tech"])
app.include_router(visual_merch_elements_router,prefix="/FASTAPI", tags=["Visual Merchandising Elements"])
app.include_router(depreciation_router,prefix="/FASTAPI", tags=["Depreciation"])
app.include_router(competitor_category_analyses_router, prefix="/FASTAPI", tags=["Competitor Category Analyses"])
# app.include_router(store_investment_summary_router, prefix="/FASTAPI", tags=["Store Investment Summary"])
# app.include_router(consumer_preferences_research_router, prefix="/FASTAPI", tags=["Consumer Preferences Research"])
app.include_router(pre_select_category_router, prefix="/FASTAPI", tags=["Pre Selected Category"])
app.include_router(gross_margin_contribution_router, prefix="/FASTAPI", tags=["Gross Margin Contribution"])
app.include_router(vendor_metrics_priority_list_router, prefix="/FASTAPI", tags=["Vendor Metrics priority List"])
app.include_router(vendor_scorecard_router, prefix="/FASTAPI", tags=["Vendor Scorecard"])
app.include_router(private_lablling_router, prefix="/FASTAPI", tags=["Private Lablling"])
app.include_router(category_captinship_planning_router, prefix="/FASTAPI", tags=["Category Captinship Planning"])
app.include_router(additional_installation_router, prefix="/FASTAPI", tags=["Additional Installation"])
app.include_router(sales_estimate_router, prefix="/FASTAPI", tags=["Sales Estimate"])
app.include_router(rent_expenses_router, prefix="/FASTAPI", tags=["Rent Expenses"])
app.include_router(competitor_pricing_analysis_router, prefix="/FASTAPI", tags=["Competitor Pricing Analysis"])
app.include_router(store_formate_pricing_router, prefix="/FASTAPI", tags=["Store Formate pricing Strategies"])
app.include_router(corporate_store_router, prefix="/FASTAPI", tags=["Corporate Store"])
app.include_router(category_definition_excel_router, prefix="/FASTAPI", tags=["Training Talent Management Excel"])
app.include_router(competitor_analysis_comparison_router, prefix="/FASTAPI", tags=["Competitor Analysis Comparison"])
app.include_router(corporate_concept_office_router, prefix="/FASTAPI", tags=["Corporate Concept Office"])
app.include_router(utility_router, prefix="/FASTAPI", tags=["Utility"])
app.include_router(operating_expenses_router, prefix="/FASTAPI", tags=["Operating Expenses"])
app.include_router(store_level_staff_router, prefix="/FASTAPI", tags=["Store Level Staff"])
app.include_router(centralised_and_direct_router, prefix="/FASTAPI", tags=["Centralised and Direct"])
app.include_router(category_wish_inventory_routre, prefix="/FASTAPI", tags=["Category Wish Inventory"])
app.include_router(shrinkage_areas_reasons_router, prefix="/FASTAPI", tags=["Shrinkage Areas Reasons"])
app.include_router(inventory_excel_router, prefix="/FASTAPI", tags=["Inventory Excel"])
app.include_router(online_policies_router, prefix="/FASTAPI", tags=["Online Policies Excel"])
app.include_router(sales_router, prefix="/FASTAPI", tags=["Sales"])
app.include_router(recurring_operating_router, prefix="/FASTAPI", tags=["Recurring Operating"])
app.include_router(digital_asset_router, prefix="/FASTAPI", tags=["Digital Asset"])
app.include_router(marketing_competitor_router, prefix="/FASTAPI", tags=["Marketing Competitor"])
app.include_router(competitorintensity_router, prefix="/FASTAPI", tags=["Competitor Intensity"])
app.include_router(projected_market_share_router, prefix="/FASTAPI", tags=["Projected Market Share"])
app.include_router(location_spillage_router, prefix="/FASTAPI", tags=["Location Spillage Factor"])
app.include_router(location_details_router, prefix="/FASTAPI", tags=["Location Details"])
app.include_router(electrical_cabling_router, prefix="/FASTAPI", tags=["Electrical Cabling"])
app.include_router(category_pricing_strategis_router, prefix="/FASTAPI", tags=["Category Pricing Strategis"])
app.include_router(define_your_promotions_router, prefix="/FASTAPI", tags=["Define Your Promotions"])
app.include_router(promotion_competitor_analysis_router, prefix="/FASTAPI", tags=["Promotion Competitor Analysis"])
app.include_router(recovery_promotional_router, prefix="/FASTAPI", tags=["Recovery of Promotional"])
app.include_router(customer_engagement_router, prefix="/FASTAPI", tags=["Customer Engagement Strategies"])
app.include_router(competitor_loyalty_router, prefix="/FASTAPI", tags=["Competitor Loyalty"])
app.include_router(brand_attribute_assessment_router, prefix="/FASTAPI", tags=["Brand Attribute Assessment"])
app.include_router(branding_attributes_router, prefix="/FASTAPI", tags=["Branding Attributes"])
app.include_router(integrated_marketing_router, prefix="/FASTAPI", tags=["Integrated Marketing"])
app.include_router(annexures_router, prefix="/FASTAPI",tags=["Annexures"])
app.include_router(optimising_assets_router, prefix="/FASTAPI", tags=["Optimising Assets"])
app.include_router(short_negotiation_final_router, prefix="/FASTAPI", tags=["Short Negotiation Final"])
app.include_router(margin_and_sales_contribution_analysis_router, prefix="/FASTAPI", tags=["Margin and Sales Contribution Analysis"])
app.include_router(online_pre_select_service_router, prefix="/FASTAPI", tags=["Online Pre Selected Service"])
app.include_router(adapting_supply_chain_router, prefix="/FASTAPI", tags=["Adapting Supply Chain"])
app.include_router(critical_for_business_router, prefix="/FASSTAPI", tags=["Critical for Business"])
app.include_router(expanded_performance_metrics_router, prefix="/FASTAPI", tags=["Expanded Performance Metrics"])
app.include_router(categories_under_promotions_router, prefix="/FASTAPI", tags=["Categories Under Promotions"])
app.include_router(comparative_analysis_router, prefix="/FASTAPI", tags=["Comparative Analysis"])
app.include_router(measuring_sales_profitability_router, prefix="/FASTAPI", tags=["Measuring Sales Profitability"])
app.include_router(pre_selected_service_router, prefix="/FASTAPI", tags=["Pre Selected Service"])
app.include_router(concept_office_router, prefix="/FASTAPI", tags=["Concept Office"])
app.include_router(store_investment_summary_router, prefix="/FASTAI", tags=["Store Investment Summary"])
app.include_router(summary_router, prefix="/FASTAPI", tags=["Summary"])
app.include_router(cash_conversion_cycle_router, prefix="/FASTAPI", tags=["Cash Conversion Cycle"])
app.include_router(visual_merch_Strategy_router, prefix="/FASTAPI", tags=["Visual Merchandising Strategy"])
app.include_router(stu_router, prefix="/FASTAPI", tags=["Student Excel"])
app.include_router(master_router, prefix="/FASTAPI", tags=["Master"])
app.include_router(user_simulation_router, prefix="/FASTAPI", tags=["User Simulation"])
app.include_router(category_simulation_router, prefix="/FASTAPI", tags=["Category Simulation"])
app.include_router(physical_store_formats_router, prefix="/FASTAPI", tags=["Physical Store Formats"])
app.include_router(cap_ex_refurbish_router, prefix="/FASTAPI", tags=["Cap-Ex Refurbish"])
app.include_router(online_store_format_router, prefix="/FASTAPI", tags=["Online Store Format"])
app.include_router(module_1_report_router, prefix="/FASTAPI", tags=["Module 1"])
app.include_router(module_2_report_router, prefix="/FASTAPI", tags=["Module 2"])
app.include_router(module_3_report_router, prefix="/FASTAPI", tags=["Module 3"])
app.include_router(module_4_report_router, prefix="/FASTAPI", tags=["Module 4"])
app.include_router(module_5_report_router, prefix="/FASTAPI", tags=["Module 5"])
app.include_router(module_6_report_router, prefix="/FASTAPI", tags=["Module 6"])
app.include_router(module_7_report_router, prefix="/FASTAPI", tags=["Module 7"])
app.include_router(module_8_report_router, prefix="/FASTAPI", tags=["Module 8"])
app.include_router(module_9_report_router, prefix="/FASTAPI", tags=["Module 9"])
app.include_router(module_10_report_router, prefix="/FASTAPI", tags=["Module 10"])
app.include_router(all_content_router, prefix="/FASTAPI", tags=["All Content"])
app.include_router(promotion_calender_router, prefix="/FASTAPI", tags=["Promotion Calender"])
app.include_router(institution_router, prefix="/FASTAPI", tags=["Institution"])


# HTTP Exception Handler
@app.exception_handler(HTTPException)
async def exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
    """Handle HTTP exceptions."""
    return http_exception_error_handler(request, exc)  # Use custom HTTP exception handler

# MySQL Exception Handler
@app.exception_handler(ProgrammingError)
async def programming_error_handler(request: Request, exc: ProgrammingError) -> JSONResponse:
    """Handle MySQL ProgrammingError exceptions."""
    return await handle_programming_error(request, exc)  # Use custom programming error handler

# General Exceptions
@app.exception_handler(Exception)
async def generic_exception_handler(request: Request, exc: Exception) -> JSONResponse:
    """Handle generic exceptions."""
    return await handle_generic_exception_handler(request, exc)  # Use custom generic exception handler

# Operational Errors
@app.exception_handler(OperationalError)
async def operational_error_handler(request: Request, exc: OperationalError) -> HTTPException:
    raise await handel_operational_error_handler(request, exc)

# Attribute Errors
@app.exception_handler(AttributeError)
async def attribute_error_handler(request: Request, exc: AttributeError)-> HTTPException:
    return await handel_attribute_error_handler(request, exc)

# Run Migrations
@app.get("/migrate",response_model_exclude_none=True)
async def run_migrations(message: str)-> CustomResponse:
    try:
        # subprocess.run(['alembic', 'downgrade', '<revision>'], shell=True)
        # Run Alembic revision command
        subprocess.run(['alembic', 'revision', '--autogenerate', '-m', '"{}"'.format(message)])
        # Run Alembic upgrade command
        subprocess.run(
            ["alembic", "upgrade", "head"]
        )
        return CustomResponse(status="1", message="Migration successful")
    
    except subprocess.CalledProcessError as e:
        raise HTTPException(status_code=500, detail=str(e))
    
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
    

app.mount("/uploads",StaticFiles(directory="uploads"),name="uploads")    


# Create OAuth2PasswordBearer instances for both user and student logins
user_oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/FASTAPI/user/login")
# student_oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/FASTAPI/student/login")



# Manually define the OpenAPI schema to include both OAuth2 flows (User and Student)
@app.on_event("startup")
def on_startup():
    app.openapi_schema = {
        "openapi": "3.0.0",
        "info": {
            "title": "My API",
            "version": "1.0.0",
            "description": "API Documentation with User and Student Login",
        },
        "paths": {
            "/some-protected-route": {
                "get": {
                    "security": [
                        {"user_oauth2": []},
                        {"student_oauth2": []},
                    ],  # Both flows (User and Student) are shown here
                    "operationId": "getSomeProtectedRoute",
                    "summary": "A protected route for both user and student",
                    "responses": {
                        "200": {"description": "Successful response"},
                    },
                }
            },
        },
        "components": {
            "securitySchemes": {
                "user_oauth2": {
                    "type": "oauth2",
                    "flow": {
                        "password": {
                            "tokenUrl": "/FASTAPI/user/login",  # User login token URL
                        }
                    }
                },
                # "student_oauth2": {
                #     "type": "oauth2",
                #     "flow": {
                #         "password": {
                #             "tokenUrl": "/FASTAPI/student/login",  # Student login token URL
                #         }
                #     }
                # },
            },
        }
    }

# Define a protected route that can be accessed with either user or student login
@app.get("/some-protected-route")
def get_some_protected_route(
    user: str = Depends(user_oauth2_scheme),  # Use user OAuth2 token
):
    return {"message": "This is a protected route", "user": user}

# # Define a student-specific route
# @app.get("/student-protected-route")
# def get_student_protected_route(
#     student: str = Depends(student_oauth2_scheme),  # Use student OAuth2 token
# ):
#     return {"message": "This is a protected route for students", "student": student}


app.mount("/uploaded_files", StaticFiles(directory="uploaded_files"), name="uploaded_files")

