// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { InteractiveIo } from "interactive-app";
import { ChatPrinter } from "../chatPrinter.js";
import {
    BreakPointSuggestions,
    Breakpoint,
    Bug,
    CodeAnswer,
    CodeDocumentation,
    CodeReview,
    LineDoc,
    LineReview,
    RelevantLine,
} from "code-processor";
import chalk from "chalk";

export class CodePrinter extends ChatPrinter {
    constructor(io: InteractiveIo) {
        super(io);
    }

    public writeCodeLines(lines: string[]): void {
        for (let i = 0; i < lines.length; ++i) {
            this.writeCodeLine(i + 1, lines[i]);
        }
    }

    public writeCodeLine(lineNumber: number, line: string): void {
        this.write(`${lineNumber} `);
        this.writeInColor(chalk.cyanBright, line);
    }

    public writeBug(bug: Bug) {
        this.writeInColor(
            chalk.redBright,
            `⚠️ ${bug.severity}: ${bug.comment}`,
        );
    }

    public writeComment(comment: LineReview) {
        this.writeInColor(
            chalk.white,
            `💬 ${comment.severity}: ${comment.comment}`,
        );
    }

    public writeBreakpoint(breakpoint: Breakpoint) {
        this.writeInColor(
            chalk.redBright,
            `🛑 ${breakpoint.priority}: ${breakpoint.comment}`,
        );
    }

    public writeRelevantLine(line: RelevantLine) {
        this.writeInColor(
            chalk.redBright,
            `💡 ${line.relevance}: ${line.comment}`,
        );
    }

    public writeDocLine(line: LineDoc) {
        this.writeInColor(chalk.greenBright, `✍🏼 ${line.comment}`);
    }

    public writeCodeReview(
        line: string,
        lineNumber: number,
        review: CodeReview,
    ): void {
        if (review.bugs) {
            const bug = review.bugs.find((b) => b.lineNumber === lineNumber);
            if (bug) {
                this.writeBug(bug);
            }
        }

        if (review.comments) {
            const comment = review.comments.find(
                (c) => c.lineNumber === lineNumber,
            );
            if (comment) {
                this.writeComment(comment);
            }
        }
    }

    public writeBreakpoints(
        line: string,
        lineNumber: number,
        review: BreakPointSuggestions,
    ): void {
        if (review.breakPoints) {
            const breakpoint = review.breakPoints.find(
                (b) => b.lineNumber === lineNumber,
            );
            if (breakpoint) {
                this.writeBreakpoint(breakpoint);
            }
        }
    }

    public writeAnswer(
        line: string,
        lineNumber: number,
        answer: CodeAnswer,
    ): void {
        if (answer.answerLines) {
            const relevantLine = answer.answerLines.find(
                (l) => l.lineNumber === lineNumber,
            );
            if (relevantLine) {
                this.writeRelevantLine(relevantLine);
            }
        }
    }

    public writeDocs(
        line: string,
        lineNumber: number,
        docs: CodeDocumentation,
    ): void {
        if (docs.comments) {
            const relevantLine = docs.comments.find(
                (l) => l.lineNumber === lineNumber,
            );
            if (relevantLine) {
                this.writeDocLine(relevantLine);
            }
        }
    }
}
