import logging
from datetime import datetime

from requests import Response

from cg.apps.tb.api import TrailblazerAPI
from cg.constants import Workflow
from cg.store.models import Analysis, Case, CaseSample, Sample
from cg.store.store import Store

LOG = logging.getLogger(__name__)


class MarkAsDeliveredService:
    def __init__(self, status_db: Store, trailblazer_api: TrailblazerAPI) -> None:
        self.status_db = status_db
        self.trailblazer_api = trailblazer_api

    def mark_analyses(self, analyses: list[Analysis]) -> Response:
        """Mark samples as delivered in StatusDB and the analysis as delivered in Trailblazer."""
        trailblazer_ids = []
        for analysis in analyses:
            self._mark_samples_in_analysis(analysis)
            trailblazer_ids.append(analysis.trailblazer_id)
        return self.trailblazer_api.mark_analyses_as_delivered(trailblazer_ids)

    def _mark_samples_in_analysis(self, analysis: Analysis) -> None:
        case: Case = analysis.case
        LOG.info(f"Marking samples as delivered for case {case.internal_id}")
        for case_sample in case.links:
            if self._should_sample_be_delivered(case_sample):
                case_sample.sample.delivered_at = datetime.now()

    def _should_sample_be_delivered(self, case_sample: CaseSample) -> bool:
        return (
            case_sample.should_deliver_sample
            and not case_sample.sample.delivered_at
            and self._passes_on_reads(case_sample)
        )

    @staticmethod
    def _passes_on_reads(case_sample: CaseSample) -> bool:
        case: Case = case_sample.case
        sample: Sample = case_sample.sample
        if (
            case.data_analysis in [Workflow.MICROSALT, Workflow.TAXPROFILER]
            and not sample.is_negative_control
        ):
            return sample.reads >= sample.expected_reads_for_sample  # type: ignore Illumina sample
        else:
            return True
