import { FC, useEffect, useRef, useState } from 'react';
import { useDraggableLoginWindow } from '../hooks/useDraggableLoginWindow';
import { interpolate, t } from '../utils/i18n';
import { resolveNewsImage, resolveNewsLink } from '../utils/news';
import { BaseButton } from '../../../common/BaseButton';
import { NativeTextTree } from '../../../common/native-text/NativeTextTree';

interface NewsItem {
    id: number;
    title: string;
    body: string;
    image: string | null;
    linkText: string;
    linkUrl: string;
}

interface RawNewsItem {
    id?: number;
    title?: string;
    body?: string;
    image?: string | null;
    link?: string;
    linkUrl?: string;
    linkText?: string;
}

const normalizeNewsItem = (raw: RawNewsItem, fallbackId: number): NewsItem => ({
    id: typeof raw.id === 'number' ? raw.id : fallbackId,
    title: typeof raw.title === 'string' ? raw.title : '',
    body: typeof raw.body === 'string' ? raw.body : '',
    image: typeof raw.image === 'string' && raw.image.length ? interpolate(raw.image) : null,
    linkText: typeof raw.linkText === 'string' ? raw.linkText : '',
    linkUrl: interpolate((typeof raw.linkUrl === 'string' && raw.linkUrl) || (typeof raw.link === 'string' ? raw.link : ''))
});

interface NewsWindowProps {
    newsUrl: string;
}

const NEWS_AUTO_ADVANCE_MS = 10000;

export const NewsWindow: FC<NewsWindowProps> = ({ newsUrl }) => {
    const [items, setItems] = useState<NewsItem[] | null>(null);
    const [failed, setFailed] = useState(false);
    const [index, setIndex] = useState(0);
    const [autoTick, setAutoTick] = useState(0);
    const stackRef = useRef<HTMLDivElement>(null);
    const { style: dragStyle, dragging, handleProps } = useDraggableLoginWindow('news', stackRef);

    useEffect(() => {
        if (!newsUrl) {
            setFailed(true);
            return;
        }
        let cancelled = false;
        const controller = new AbortController();

        fetch(newsUrl, { credentials: 'omit', signal: controller.signal })
            .then(async (r) => {
                if (!r.ok) throw new Error('status ' + r.status);
                return r.json();
            })
            .then((json: unknown) => {
                if (cancelled) return;
                const rawList = Array.isArray((json as { news?: unknown })?.news)
                    ? (json as { news: RawNewsItem[] }).news
                    : Array.isArray(json)
                      ? (json as RawNewsItem[])
                      : [];
                setItems(rawList.map((raw, idx) => normalizeNewsItem(raw, idx + 1)));
            })
            .catch(() => {
                if (!cancelled) setFailed(true);
            });
        return () => {
            cancelled = true;
            controller.abort();
        };
    }, [newsUrl]);

    useEffect(() => {
        if (!items || items.length < 2) return;
        const id = window.setTimeout(() => {
            setIndex((i) => (i + 1) % items.length);
        }, NEWS_AUTO_ADVANCE_MS);
        return () => window.clearTimeout(id);
    }, [items, index, autoTick]);

    if (failed) return null;
    if (!items || !items.length) return null;

    const current = items[Math.min(index, items.length - 1)];
    const hasMany = items.length > 1;
    const bumpAuto = () => setAutoTick((t) => t + 1);
    const prev = () => {
        setIndex((i) => (i - 1 + items.length) % items.length);
        bumpAuto();
    };
    const next = () => {
        setIndex((i) => (i + 1) % items.length);
        bumpAuto();
    };

    const safeLinkUrl = resolveNewsLink(current.linkUrl);
    const safeImageSrc = resolveNewsImage(current.image);
    const openLink = () => {
        if (!safeLinkUrl) return;
        window.open(safeLinkUrl, '_blank', 'noopener,noreferrer');
    };

    return (
        <NativeTextTree>
            <div className={`login-news-stack${dragging ? ' is-dragging' : ''}`} ref={stackRef} style={dragStyle}>
                <div className="news-card-wrapper" key={current.id}>
                    <div className="octane-login-card octane-card-shell octane-news-card">
                        <div
                            className="card-title octane-card-header-shell login-drag-handle"
                            title={t('nitro.login.window.drag_hint', 'Drag to move, double-click to reset')}
                            {...handleProps}
                        >
                            <span className="octane-card-title">{t('nitro.login.news.title', 'Hotel News')}</span>
                        </div>
                        <div className="card-body octane-card-content-shell news-body">
                            {safeImageSrc && (
                                <div className="news-image">
                                    <img
                                        src={safeImageSrc}
                                        alt={current.title || 'news'}
                                        onError={(e) => {
                                            e.currentTarget.style.display = 'none';
                                        }}
                                    />
                                </div>
                            )}
                            <div className="news-headline">{current.title}</div>
                            {current.body && <div className="news-text">{current.body}</div>}

                            <div className="news-footer">
                                {current.linkText && safeLinkUrl ? (
                                    <BaseButton type="button" className="ok-button news-link-button" onClick={openLink}>
                                        {current.linkText}
                                    </BaseButton>
                                ) : (
                                    <span />
                                )}

                                {hasMany && (
                                    <div className="news-pager">
                                        <BaseButton type="button" className="arrow-btn" aria-label="Previous news" onClick={prev}>
                                            &lsaquo;
                                        </BaseButton>
                                        <span className="news-counter">
                                            {index + 1}/{items.length}
                                        </span>
                                        <BaseButton type="button" className="arrow-btn" aria-label="Next news" onClick={next}>
                                            &rsaquo;
                                        </BaseButton>
                                    </div>
                                )}
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </NativeTextTree>
    );
};
