from typing import List

from db.db import get_db
from db.models import InvestorTable
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from services.crm import folk
from sqlalchemy.orm import Session, selectinload

router = APIRouter(prefix="/folk", tags=["Folk CRM"])


class GroupResponse(BaseModel):
    id: str
    name: str


class SyncInvestorsRequest(BaseModel):
    investor_ids: List[int]
    group_id: str


class SyncResult(BaseModel):
    investor_id: int
    investor_name: str
    company_id: str
    company_name: str
    team_members_synced: int
    person_ids: List[str]


class SyncInvestorsResponse(BaseModel):
    success: bool
    synced_count: int
    results: List[SyncResult]
    errors: List[dict]


@router.get("/groups", response_model=List[GroupResponse])
def get_folk_groups():
    """Get all groups from Folk CRM.

    Returns a list of groups with their id and name that can be used
    to sync investors to Folk.
    """
    try:
        groups_data = folk.get_groups()
        items = groups_data.get("data", {}).get("items", [])

        return [GroupResponse(id=item["id"], name=item["name"]) for item in items]
    except Exception as e:
        raise HTTPException(
            status_code=500, detail=f"Failed to fetch groups from Folk: {str(e)}"
        )


@router.post("/sync-investors", response_model=SyncInvestorsResponse)
def sync_investors_to_folk(
    request: SyncInvestorsRequest, db: Session = Depends(get_db)
):
    """Sync investors to Folk CRM as companies with their team members as people.

    Takes a list of investor IDs and a Folk group ID, then:
    1. Creates each investor as a company in the specified Folk group
    2. Creates each team member as a person linked to that company

    Args:
        investor_ids: List of investor IDs from the database
        group_id: Folk group ID where investors should be added

    Returns:
        Summary of sync operation including successes and errors
    """
    # Fetch investors with their team members
    investors = (
        db.query(InvestorTable)
        .options(
            selectinload(InvestorTable.team_members),
            selectinload(InvestorTable.sectors),
        )
        .filter(InvestorTable.id.in_(request.investor_ids))
        .all()
    )

    if not investors:
        raise HTTPException(
            status_code=404, detail="No investors found with the provided IDs"
        )

    results = []
    errors = []

    for investor in investors:
        try:
            # Create company in Folk
            company_data = folk.create_company(
                name=investor.name,
                group_id=request.group_id,
                website=investor.website,
                description=investor.description,
                addresses=[investor.headquarters] if investor.headquarters else None,
            )

            company_id = company_data.get("data", {}).get("id")
            if not company_id:
                errors.append(
                    {
                        "investor_id": investor.id,
                        "investor_name": investor.name,
                        "error": "No company ID returned from Folk API",
                    }
                )
                continue

            # Create team members as people
            person_ids = []
            team_members_synced = 0

            for member in investor.team_members:
                try:
                    # Extract first name and last name from full name
                    name_parts = member.name.split(maxsplit=1)
                    first_name = name_parts[0] if name_parts else member.name
                    last_name = name_parts[1] if len(name_parts) > 1 else ""

                    # Build URLs list from source_url if available
                    urls_list = None
                    if hasattr(member, "source_url") and member.source_url:
                        urls_list = [member.source_url]

                    # Build job title from title or role
                    job_title = None
                    if hasattr(member, "title") and member.title:
                        job_title = member.title
                    elif hasattr(member, "role") and member.role:
                        job_title = member.role

                    person_data = folk.create_person(
                        first_name=first_name,
                        last_name=last_name,
                        email=member.email,
                        company_id=company_id,
                        group_id=request.group_id,
                        urls=urls_list,
                        jobTitle=job_title,
                    )

                    person_id = person_data.get("data", {}).get("id")
                    if person_id:
                        person_ids.append(person_id)
                        team_members_synced += 1
                except Exception as person_error:
                    # Log person creation error but continue with other members
                    errors.append(
                        {
                            "investor_id": investor.id,
                            "investor_name": investor.name,
                            "team_member_name": member.name,
                            "error": f"Failed to create person: {str(person_error)}",
                        }
                    )

            results.append(
                SyncResult(
                    investor_id=investor.id,
                    investor_name=investor.name,
                    company_id=company_id,
                    company_name=company_data.get("data", {}).get(
                        "name", investor.name
                    ),
                    team_members_synced=team_members_synced,
                    person_ids=person_ids,
                )
            )

        except Exception as e:
            errors.append(
                {
                    "investor_id": investor.id,
                    "investor_name": investor.name,
                    "error": str(e),
                }
            )

    return SyncInvestorsResponse(
        success=len(results) > 0,
        synced_count=len(results),
        results=results,
        errors=errors,
    )
