from typing import Dict, List

from sqlalchemy.orm import Session

from src.core.log_conf import logger
from src.db.models.comic import Comic, Issue
from src.schema.comics.artist import ArtistResponse
from src.schema.comics.comic import ComicResponse, ComicSchema
from src.schema.comics.comic_details import ComicDetailsResponse, ComicWorktypeArtistResponse
from src.schema.comics.issue import IssueResponse
from src.schema.comics.issue_details import IssueDetailsResponse
from src.schema.comics.publisher import PublisherResponse
from src.schema.comics.volume import VolumeResponse
from src.schema.comics.worktype import WorktypeResponse


def list_comics(db: Session) -> List[Comic]:
    comics = db.query(Comic).all()
    return comics


def get_issue_details(issue: Issue) -> IssueDetailsResponse:
    response = IssueDetailsResponse(
        id=issue.id,
        issue_number=str(issue.issue_number),
        in_stock=bool(issue.in_stock),
        is_read=bool(issue.is_read),
        comic=ComicResponse(id=issue.comic.id, title=issue.comic.title, completed=issue.comic.completed),
        volume=VolumeResponse(id=issue.volume.id, name=issue.volume.name)
    )
    return response


def update_comic(comic: ComicSchema, comic_id: str, db: Session) -> type[Comic] | None:
    logger.info(f"update_comic: {comic} with {comic_id}")
    comic = db.get(Comic, comic_id) # type: ignore
    return comic # type: ignore

def get_short_info(comic: Comic) -> ComicResponse:
    response = ComicResponse(
        id=comic.id,
        title=str(comic.title),
        completed=bool(comic.completed == 1)
    )
    return response

def get_comic_details(comic: Comic) -> ComicDetailsResponse:
    volumes: List[VolumeResponse] = []
    for volume in comic.volumes:
        volumes.append(VolumeResponse(id=volume.id, name=volume.name))
    issues: List[IssueResponse] = []
    for issue in comic.issues:
        issues.append(IssueResponse(
            id=issue.id,
            issue_number=issue.issue_number,
            in_stock=issue.in_stock,
            is_read=issue.is_read
        ))
    works: List[ComicWorktypeArtistResponse] = []
    works_map: Dict[str, ComicWorktypeArtistResponse] = {}
    for work in comic.comic_works:
        worktype_id = work.work_type.id
        if worktype_id in works_map:
            artist = ArtistResponse(id=work.artist.id, name=work.artist.name)
            works_map[worktype_id].artists.append(artist)
            logger.info(f"add artist to response map: {artist} -> {works_map}")
            print(f"add artist to response map: {artist} -> {works_map}")
        else:
            works_map[worktype_id] = ComicWorktypeArtistResponse(
                worktype=WorktypeResponse(id=worktype_id, name=work.work_type.name), 
                artists=[ArtistResponse(id=work.artist.id, name=work.artist.name)]
            )
    for value in works_map.values():
        works.append(value)
    response = ComicDetailsResponse(
        id=str(comic.id),
        created=str(comic.created_date),
        title=str(comic.title),
        completed=bool(comic.completed),
        current_order=bool(comic.current_order),
        weblink=str(comic.weblink),
        publisher=PublisherResponse(id=comic.publisher.id, name=comic.publisher.name),
        issues=issues,
        volumes=volumes,
        works=works
    )
    return response
