import time
import typer
from typing import Optional, List
from typing_extensions import Annotated
from rich.progress import Progress, SpinnerColumn, TextColumn
from ..utils.vcf_to_fasta import vcf_bam_to_fasta

app = typer.Typer()


@app.command()
def vcf2fasta(
    vcf: Annotated[list[str],typer.Option("--vcf", help="Path to input VCF file(s). Can be specified multiple times.")],
    bam: Annotated[str, typer.Option("--bam", help="Path to Tumor RNA-seq BAM file.")],
    output: Annotated[str, typer.Option("--output", "-o", help="Path to output FASTA file.")],
    protein_sequence_length: Annotated[Optional[int], typer.Option(
        "--protein-sequence-length", help="Length of protein sequence to extract around each mutation.")] = None,
    centered_sequence_length: Annotated[Optional[int], typer.Option(
        "--centered-sequence-length", help="Fixed length of protein sequence centered on the mutation site.")] = None,
    min_alt_rna_reads: Annotated[int, typer.Option(
        "--min-alt-rna-reads", help="Minimum number of RNA reads supporting alternate allele.")] = 2,
    min_alt_rna_fragments: Annotated[int, typer.Option(
        "--min-alt-rna-fragments", help="Minimum number of RNA fragments supporting alternate allele.")] = 2,
    min_variant_sequence_coverage: Annotated[int, typer.Option(
        "--min-variant-sequence-coverage", help="Minimum coverage at variant position.")] = 1,
    min_mapping_quality: Annotated[int, typer.Option(
        "--min-mapping-quality", help="Minimum mapping quality for reads.")] = 1,
    min_base_quality: Annotated[int, typer.Option(
        "--min-base-quality", help="Minimum base quality.")] = 1,
    use_duplicate_reads: Annotated[bool, typer.Option(
        "--use-duplicate-reads", help="Use duplicate reads.")] = False,
    use_secondary_alignments: Annotated[bool, typer.Option(
        "--use-secondary-alignments", help="Use secondary alignments.")] = False,
    genome: Annotated[Optional[str], typer.Option(
        "--genome", help="Genome reference (e.g., GRCh37, GRCh38).")] = None,
):
    """
    Convert VCF file(s) with RNA BAM file to FASTA protein sequences.

    This command processes variants from VCF file(s) with RNA-seq data from a BAM file
    using isovar, and writes the resulting mutant protein sequences to a FASTA file.
    Multiple VCF files from different variant callers (e.g., Mutect, Strelka) can be combined.
    """

    with Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}"),
        transient=True,
    ) as progress:
        try:
            progress.add_task(
                description="Processing VCF and BAM files...", total=None)
            start = time.time()

            sequences_written = vcf_bam_to_fasta(
                vcf_paths=vcf,
                bam_path=bam,
                output_fasta_path=output,
                protein_sequence_length=protein_sequence_length,
                centered_sequence_length=centered_sequence_length,
                min_alt_rna_reads=min_alt_rna_reads,
                min_alt_rna_fragments=min_alt_rna_fragments,
                min_variant_sequence_coverage=min_variant_sequence_coverage,
                min_mapping_quality=min_mapping_quality,
                use_duplicate_reads=use_duplicate_reads,
                use_secondary_alignments=use_secondary_alignments,
                min_base_quality=min_base_quality,
                genome=genome
            )

            end = time.time()
            elapsed = end - start
            time_cost = f"{int(elapsed // 3600)}h{int((elapsed % 3600) // 60)}m{elapsed % 60:.2f}s"

            progress.add_task(
                description=f"Successfully wrote {sequences_written} protein sequences", total=None)
            print(
                f"Successfully wrote {sequences_written} protein sequences to {output}")
            print(f"Time cost: {time_cost}")

        except Exception as e:
            print(f"Error: {e}")
            progress.add_task(description="Processing failed", total=None)
            raise typer.Exit(code=1)
