import * as React from 'react';
import { Issue } from './reportManagerSchema';
import { getLabelColors } from './reportManagerUtils';
import ReactMarkdown from 'react-markdown';
import rehypeRaw from 'rehype-raw';
import remarkGfm from 'remark-gfm';

// Mini components to render issues

interface IssueCardProps {
    issue: Issue;
    onSelect: () => void;
}
export const IssueCard = ({ issue, onSelect }: IssueCardProps) => {
    return (
        <div className="issue-card" onClick={onSelect}>
            <div className="issue-top">
                <label className="issue-label">#{issue.number}</label>
                <div className="issue-tags">
                    {issue.labels.map(label => {
                        const labelString = typeof label === 'string' ? label : label.name ?? '';
                        const colors = getLabelColors(labelString);
                        return <Tag key={labelString} text={labelString} backgroundColor={colors[0]} color={colors[1]} />;
                    })}
                </div>
            </div>
            <h3 className="issue-title">{issue.title}</h3>
        </div>
    );
};

interface IssueViewProps {
    issue: Issue;
}

export const IssueView = ({ issue }: IssueViewProps) => {
    const [issueBody, setIssueBody] = React.useState('');

    const isVideoValid = (src: string) => {
        const videoElement = document.createElement('video');
        const validPromise: Promise<boolean> = new Promise(resolve => {
            videoElement.addEventListener('loadeddata', () => resolve(true));
            videoElement.addEventListener('error', () => resolve(false));
        });
        videoElement.src = src;
        return validPromise;
    };

    const getLinkFromTag = async (tag: string) => {
        const regex = /src="([^"]+)"/;
        let url = '';
        const match = tag.match(regex);
        if (match) {
            url = match[1];
        }

        if (url.startsWith('https://github.com/brown-dash/Dash-Web/assets')) {
            return `\n${url} (Not authorized to display image here)`;
        }
        return await getTagFromUrl(url);
    };

    const getTagFromUrl = async (url: string) => {
        const imgRegex = /https:\/\/browndash\.com\/files[/\\]images/;
        const videoRegex = /https:\/\/browndash\.com\/files[/\\]videos/;
        const audioRegex = /https:\/\/browndash\.com\/files[/\\]audio/;

        if (imgRegex.test(url) || url.includes('user-images.githubusercontent.com')) {
            return `\n${url}\n<img width="100%" alt="Issue asset" src=${url} />\n`;
        } else if (videoRegex.test(url)) {
            const videoValid = await isVideoValid(url);
            if (!videoValid) return `\n${url} (This video could not be loaded)\n`;
            return `\n${url}\n<video class="report-default-video" width="100%" controls alt="Issue asset" src=${url} />\n`;
        } else if (audioRegex.test(url)) {
            return `\n${url}\n<audio src=${url} controls />\n`;
        } else {
            return url;
        }
    };

    const parseBody = async (body: string) => {
        const imgTagRegex = /<img\b[^>]*\/?>/;
        const fileRegex = /https:\/\/browndash\.com\/files/;
        const parts = body.split('\n');

        const modifiedParts = await Promise.all(
            parts.map(async part => {
                if (imgTagRegex.test(part)) {
                    return `\n${await getLinkFromTag(part)}\n`;
                } else if (fileRegex.test(part)) {
                    const tag = await getTagFromUrl(part);
                    return tag;
                } else {
                    return part;
                }
            })
        );

        setIssueBody(modifiedParts.join('\n'));
    };

    React.useEffect(() => {
        parseBody((issue.body as string) ?? '');
    }, [issue]);

    return (
        <div className="issue-view">
            <span className="issue-label">
                Issue{' '}
                <a className="issue-link" href={issue.html_url} target="_blank">
                    #{issue.number}
                </a>
            </span>
            <h2 className="issue-title">{issue.title}</h2>
            <div className="issue-date">
                Opened on {new Date(issue.created_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })} {issue.user?.login && `by ${issue.user?.login}`}
            </div>
            {issue.labels.length > 0 && (
                <div>
                    <div className="issue-tags">
                        {issue.labels.map(label => {
                            const labelString = typeof label === 'string' ? label : label.name ?? '';
                            const colors = getLabelColors(labelString);
                            return <Tag key={labelString} text={labelString} backgroundColor={colors[0]} color={colors[1]} fontSize="12px" />;
                        })}
                    </div>
                </div>
            )}
            <ReactMarkdown children={issueBody} className="issue-content" linkTarget={'_blank'} remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]} />
        </div>
    );
};

interface TagProps {
    text: string;
    fontSize?: string;
    color?: string;
    backgroundColor?: string;
    borderColor?: string;
    border?: boolean;
    onClick?: () => void;
}

export const Tag = ({ text, color, backgroundColor, fontSize, border, borderColor, onClick }: TagProps) => {
    return (
        <div
            onClick={onClick ?? (() => {})}
            className="report-tag"
            style={{ color: color ?? '#ffffff', backgroundColor: backgroundColor ?? '#347bff', cursor: onClick ? 'pointer' : 'auto', fontSize: fontSize ?? '10px', border: border ? '1px solid' : 'none', borderColor: borderColor ?? '#94a3b8' }}>
            {text}
        </div>
    );
};
