import SurveyInfo from "../SurveyInfo/SurveyInfo.tsx";
import styles from './Results.module.css';
import {Bar, Pie} from 'react-chartjs-2';
import {Chart as ChartJS, ArcElement, Tooltip, Legend, CategoryScale, LinearScale, BarElement, Title} from 'chart.js';
import {useOutletContext} from "react-router-dom";
import {ISurvey, getSurveyById} from "../../api/SurveyApi.ts";
import ChartDataLabels from 'chartjs-plugin-datalabels';
import annotationPlugin from 'chartjs-plugin-annotation';
import Group from '../../assets/gmail_groups.svg?react';
import Send from '../../assets/send.svg?react';
import {getAllCompletions} from "../../api/CompletionApi.ts";
import {getAnswer} from "../../api/AnswerApi.ts";
import {useEffect, useState} from "react";
import {getListQuestions} from "../../api/QuestionApi.ts";
import {getAnswerVariants, IAnswerVariant} from "../../api/AnswerVariantsApi.ts";
import {getResultsFile} from "../../api/ExportResultApi.ts";

ChartJS.register(
    ArcElement, Tooltip, Legend,
    CategoryScale, LinearScale, BarElement, Title, ChartDataLabels, annotationPlugin
);

interface QuestionStats {
    questionText: string;
    totalAnswers: number;
    options: {
        text: string;
        percentage: number;
        id: number;
    }[];
    isMultipleChoice: boolean;
}

interface IAnswer {
    questionId: number;
    completionId: number;
    answerText: string;
    optionId?: number;
}

export const Results = () => {
    const { survey: initialSurvey, setSurvey } = useOutletContext<{
        survey: ISurvey;
        setSurvey: (survey: ISurvey) => void;
    }>();

    const [surveyStats, setSurveyStats] = useState({
        totalParticipants: 0,
        completionPercentage: 0,
        status: 'Активен',
        questions: [] as QuestionStats[]
    });

    const [survey, setLocalSurvey] = useState<ISurvey>(initialSurvey);
    // const [questions, setQuestions] = useState<IQuestion[]>([]);

    const handleExportToExcel = async (id: number) => {
        await getResultsFile(id)
    };

    useEffect(() => {
        const fetchSurveyData = async () => {
            try {
                const surveyData = await getSurveyById(survey.id);
                setLocalSurvey(surveyData);

                const questionsList = await getListQuestions(survey.id);
                // setQuestions(questionsList);

                const questionsWithVariants = await Promise.all(
                    questionsList.map(async (question) => {
                        const variants = await getAnswerVariants(survey.id, question.id);
                        return {
                            ...question,
                            options: variants,
                            isMultipleChoice: question.questionType !== 'SingleAnswerQuestion'
                        };
                    })
                );

                const completions = await getAllCompletions(survey.id);
                const totalParticipants = completions.length;

                const questionsWithAnswers = await Promise.all(
                    questionsWithVariants.map(async (question) => {
                        const answers = await getAnswer(question.id);
                        return {
                            ...question,
                            answers: answers
                        };
                    })
                );

                const questionsStats = questionsWithAnswers.map(question => {
                    const questionAnswers = question.answers as IAnswer[];

                    let uniqueAnswers = questionAnswers;
                    if (question.isMultipleChoice) {
                        const groupedByCompletion = questionAnswers.reduce((acc, answer) => {
                            if (!acc[answer.completionId]) {
                                acc[answer.completionId] = [];
                            }
                            acc[answer.completionId].push(answer);
                            return acc;
                        }, {} as Record<number, IAnswer[]>);

                        uniqueAnswers = Object.values(groupedByCompletion).map(group => ({
                            ...group[0],
                            answerText: group.map(a => a.answerText).join("; ")
                        }));
                    }

                    const optionsStats = question.options.map((option: IAnswerVariant) => {
                        const count = uniqueAnswers.filter(answer =>
                            question.isMultipleChoice
                                ? answer.answerText.includes(option.text)
                                : answer.answerText === option.text
                        ).length;

                        const percentage = totalParticipants > 0
                            ? Math.round((count / totalParticipants) * 100)
                            : 0;

                        return {
                            text: option.text,
                            percentage: percentage,
                            id: option.id
                        };
                    });

                    return {
                        questionText: question.title,
                        totalAnswers: uniqueAnswers.length,
                        options: optionsStats,
                        isMultipleChoice: question.isMultipleChoice
                    };
                });

                const totalAnswersCount = questionsWithAnswers.reduce((sum, question) => {
                    if (question.isMultipleChoice) {
                        const uniqueCompletions = new Set(
                            question.answers.map((answer : IAnswer) => answer.completionId)
                        );
                        return sum + uniqueCompletions.size;
                    } else {
                        return sum + question.answers.length;
                    }
                }, 0);

                const maxPossibleAnswers = questionsWithAnswers.length * totalParticipants;
                const completionPercentage = totalParticipants > 0 && maxPossibleAnswers > 0
                    ? Math.round((totalAnswersCount / maxPossibleAnswers) * 100)
                    : 0;

                setSurveyStats({
                    totalParticipants,
                    completionPercentage,
                    status: 'Активен',
                    questions: questionsStats
                });

            } catch (error) {
                console.error('Error fetching survey data:', error);
            }
        };

        fetchSurveyData();
    }, [survey.id]);

    const colorsForPie = ['#67C587', '#C9EAD4', '#EAF6ED'];
    const colorsForBar = ['#8979FF'];

    return (
        <div className={styles.results}>
            <SurveyInfo
                titleSurvey={survey.title}
                descriptionSurvey={survey.description}
                setDescriptionSurvey={(value) => {
                    setSurvey({ ...survey, description: value });
                    setLocalSurvey({ ...survey, description: value });
                }}
                setTitleSurvey={(value) => {
                    setSurvey({ ...survey, title: value });
                    setLocalSurvey({ ...survey, title: value });
                }}
            />
            <div className={styles.statsContainer}>
                <div className={`${styles.statItem} ${styles.countAnswer}`}>
                    <h3>Количество ответов</h3>
                    <div className={styles.result}>
                        <p>{surveyStats.totalParticipants}</p>
                        <Group className={styles.imgGroup}/>
                    </div>
                </div>
                <div className={`${styles.statItem} ${styles.completion_percentage}`}>
                    <h3>Процент завершения</h3>
                    <div className={styles.result}>
                        <p>{surveyStats.completionPercentage}%</p>
                        <Send className={styles.imgSend}/>
                    </div>
                </div>
                <div className={`${styles.statItem} ${styles.status}`}>
                    <h3>Статус опроса</h3>
                    <p>{surveyStats.status}</p>
                </div>
            </div>

            {surveyStats.questions.map((question, index) => (
                <div key={index} className={styles.questionContainer}>
                    <div className={styles.questionContent}>
                        <div className={styles.textContainer}>
                            <h3>{question.questionText}</h3>
                            <p className={styles.answerCount}>Ответов: {question.totalAnswers}</p>
                        </div>

                        <div className={styles.chartContainer}>
                            {question.isMultipleChoice ? (
                                <div className={styles.barContainer}>
                                    <Bar
                                        data={{
                                            labels: question.options.map(opt => opt.text),
                                            datasets: [{
                                                label: '% выбравших',
                                                data: question.options.map(opt => opt.percentage),
                                                backgroundColor: colorsForBar,
                                                borderColor: colorsForBar,
                                                borderWidth: 2,
                                                borderRadius: 8,
                                                borderSkipped: false,
                                            }]
                                        }}
                                        options={{
                                            responsive: true,
                                            plugins: {
                                                legend: {
                                                    display: false
                                                },
                                                tooltip: { enabled: true },
                                                datalabels: { display: false },
                                                annotation: {
                                                    annotations: question.options.map((opt, i) => ({
                                                        type: 'label',
                                                        xValue: i,
                                                        yValue: opt.percentage + 5,
                                                        content: `${opt.percentage}%`,
                                                        font: { size: 1, weight: 400 },
                                                        color: '#000'
                                                    }))
                                                }
                                            },
                                            scales: {
                                                y: {
                                                    beginAtZero: true,
                                                    max: 100,
                                                    ticks: { callback: (val) => `${val}%` }
                                                },
                                                x: {
                                                    ticks: {
                                                        color: '#000000',
                                                        font: {
                                                            size: 12,
                                                            weight: 400
                                                        }
                                                    },
                                                    grid: { display: false }
                                                }
                                            }
                                        }}
                                    />
                                </div>
                            ) : (
                                <div className={styles.pieContainer}>
                                    <Pie
                                        data={{
                                            labels: question.options.map(opt => opt.text),
                                            datasets: [{
                                                data: question.options.map(opt => opt.percentage),
                                                backgroundColor: colorsForPie,
                                                borderColor: '#fff',
                                                borderWidth: 2
                                            }]
                                        }}
                                        options={{
                                            responsive: true,
                                            plugins: {
                                                legend: {
                                                    position: 'right',
                                                    labels: {
                                                        color: '#000000',
                                                        font: {
                                                            size: 12,
                                                            weight: 500
                                                        }
                                                    }
                                                },
                                                tooltip: {
                                                    callbacks: {
                                                        label: (ctx) => `${ctx.label}: ${ctx.raw}%`
                                                    }
                                                },
                                                datalabels: {
                                                    formatter: (value) => `${value}%`,
                                                    color: '#000',
                                                    font: { weight: 400, size: 12 }
                                                }
                                            },
                                            animation: { animateRotate: true }
                                        }}
                                    />
                                </div>
                            )}
                        </div>
                    </div>
                </div>
            ))}

            <button className={styles.exportButtonContainer} onClick={() => handleExportToExcel(survey.id)}>Экспорт в excel</button>
        </div>
    );
};