"use client";

import { useEffect, useRef, useState } from "react";
import { Image as ImageIcon } from "lucide-react";
import { angleDeg } from "../_lib/avatar.utils";
import { GIZMO_DIST, GIZMO_R, AVATAR_IMAGES, COLORS, FONTS } from "../_lib/avatar.constants";
import { getCanvasXY, renderBaseAvatar, renderOverlayGizmo } from "../_lib/avatar.canvas";
import { BackgroundPanel } from "./BackgroundPanel";
import { TextPanel } from "./TextPanel";
import { EffectsPanel } from "./EffectsPanel";
import { PreviewPanel } from "./PreviewPanel";

export function AvatarEditor () {
    const [ selectedImage, setSelectedImage ] = useState( AVATAR_IMAGES[ 0 ] );

    const [ customBg, setCustomBg ] = useState<string | null>( null );
    const [ customImage, setCustomImage ] = useState<string | null>( null );

    const [ text, setText ] = useState( "" );
    const [ textColor, setTextColor ] = useState( COLORS[ 0 ].value );
    const [ font, setFont ] = useState( FONTS[ 0 ].value );
    const [ fontSize, setFontSize ] = useState( 60 );
    const [ recentFonts, setRecentFonts ] = useState<string[]>( [] );
    const [ textPosition, setTextPosition ] = useState( { x: 400, y: 700 } );

    const [ useOutline, setUseOutline ] = useState( false );
    const [ outlineColor, setOutlineColor ] = useState( "#000000" );
    const [ outlineWidth, setOutlineWidth ] = useState( 4 );

    const [ useShadow, setUseShadow ] = useState( false );
    const [ shadowColor, setShadowColor ] = useState( "#000000" );
    const [ shadowBlur, setShadowBlur ] = useState( 10 );
    const [ shadowOffsetX, setShadowOffsetX ] = useState( 0 );
    const [ shadowOffsetY, setShadowOffsetY ] = useState( 0 );

    const [ useGradient, setUseGradient ] = useState( false );
    const [ gradientType, setGradientType ] = useState<"linear" | "radial">( "linear" );
    const [ gradColor1, setGradColor1 ] = useState( "#3B82F6" );
    const [ gradColor2, setGradColor2 ] = useState( "#10B981" );
    const [ gradAngle, setGradAngle ] = useState( 0 );
    const [ gradRadius, setGradRadius ] = useState( 220 );

    const [ textRotation, setTextRotation ] = useState( 0 );
    const [ isDragging, setIsDragging ] = useState( false );
    const [ isRotating, setIsRotating ] = useState( false );
    const [ rotStartDelta, setRotStartDelta ] = useState( 0 );

    const baseCanvasRef = useRef<HTMLCanvasElement>( null );
    const overlayCanvasRef = useRef<HTMLCanvasElement>( null );
    const fileInputRef = useRef<HTMLInputElement>( null );
    const [ fileKey, setFileKey ] = useState( 0 );

    const isLogoT = selectedImage === "Logo_T.png";

    useEffect( () => {
        const baseCanvas = baseCanvasRef.current;
        if ( !baseCanvas ) return;

        renderBaseAvatar( {
            canvas: baseCanvas,
            selectedImage,
            customBg,
            customImage,
            text,
            textColor,
            font,
            fontSize,
            textPosition,
            useOutline,
            outlineColor,
            outlineWidth,
            useShadow,
            shadowColor,
            shadowBlur,
            shadowOffsetX,
            shadowOffsetY,
            useGradient,
            gradientType,
            gradColor1,
            gradColor2,
            gradAngle,
            gradRadius,
            textRotation,
        } );
    }, [
        selectedImage,
        customBg,
        customImage,
        text,
        textColor,
        font,
        fontSize,
        textPosition,
        useOutline,
        outlineColor,
        outlineWidth,
        useShadow,
        shadowColor,
        shadowBlur,
        shadowOffsetX,
        shadowOffsetY,
        useGradient,
        gradientType,
        gradColor1,
        gradColor2,
        gradAngle,
        gradRadius,
        textRotation,
    ] );

    useEffect( () => {
        const overlayCanvas = overlayCanvasRef.current;
        if ( !overlayCanvas ) return;

        renderOverlayGizmo( {
            canvas: overlayCanvas,
            text,
            textPosition,
            textRotation,
            gizmoDist: GIZMO_DIST,
            gizmoRadius: GIZMO_R,
        } );
    }, [ text, textPosition, textRotation ] );

    const onPointerDown = ( e: React.PointerEvent<HTMLCanvasElement> ) => {
        if ( !text || !overlayCanvasRef.current ) return;

        const { x, y } = getCanvasXY( overlayCanvasRef.current, e );

        const theta = ( ( textRotation % 360 ) * Math.PI ) / 180;
        const gxw = textPosition.x + Math.cos( theta ) * GIZMO_DIST;
        const gyw = textPosition.y + Math.sin( theta ) * GIZMO_DIST;

        const distG = Math.hypot( x - gxw, y - gyw );
        if ( distG <= GIZMO_R + 8 ) {
            setIsRotating( true );
            const angMouse = angleDeg( x - textPosition.x, y - textPosition.y );
            const current = ( ( textRotation % 360 ) + 360 ) % 360;
            setRotStartDelta( angMouse - current );
            e.currentTarget.setPointerCapture( e.pointerId );
            return;
        }

        const distC = Math.hypot( x - textPosition.x, y - textPosition.y );
        if ( distC < Math.max( 100, fontSize * 0.9 ) ) {
            setIsDragging( true );
            e.currentTarget.setPointerCapture( e.pointerId );
        }
    };

    const onPointerMove = ( e: React.PointerEvent<HTMLCanvasElement> ) => {
        if ( ( !isDragging && !isRotating ) || !overlayCanvasRef.current ) return;

        const { x, y } = getCanvasXY( overlayCanvasRef.current, e );

        if ( isRotating ) {
            let deg = angleDeg( x - textPosition.x, y - textPosition.y ) - rotStartDelta;
            deg = ( ( deg % 360 ) + 360 ) % 360;

            if ( e.shiftKey ) {
                const step = 15;
                deg = Math.round( deg / step ) * step;
            }

            setTextRotation( deg );
            return;
        }

        if ( isDragging ) {
            setTextPosition( { x, y } );
        }
    };

    const onPointerUp = ( e: React.PointerEvent<HTMLCanvasElement> ) => {
        setIsDragging( false );
        setIsRotating( false );

        try {
            e.currentTarget.releasePointerCapture( e.pointerId );
        } catch {
            //
        }
    };

    const handleFileUpload = ( e: React.ChangeEvent<HTMLInputElement> ) => {
        const file = e.target.files?.[ 0 ];
        if ( !file ) return;

        const reader = new FileReader();
        reader.onload = ( ev ) => {
            const result = ev.target?.result as string;

            if ( isLogoT ) setCustomBg( result );
            else setCustomImage( result );

            e.currentTarget.value = "";
        };

        reader.readAsDataURL( file );
    };

    const downloadAvatar = () => {
        const baseCanvas = baseCanvasRef.current;
        if ( !baseCanvas ) return;

        const link = document.createElement( "a" );
        link.download = "avatar.png";
        link.href = baseCanvas.toDataURL( "image/png" );
        link.click();
    };

    return (
        <div className="min-h-screen bg-slate-950 text-white">
            <div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950">
                <div className="absolute inset-0 bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-indigo-900/10 via-transparent to-transparent" />

                <main className="relative container mx-auto px-4 py-12">
                    <header className="mb-14 text-center">
                        <div className="mb-5 inline-flex items-center gap-3 rounded-full border border-white/10 bg-indigo-500/10 px-5 py-2 backdrop-blur-sm">
                            <ImageIcon className="h-5 w-5 text-indigo-300" />
                            <span className="font-medium text-indigo-300">Gaming Avatar Creator</span>
                        </div>

                        <h1 className="bg-gradient-to-r from-white via-slate-200 to-white bg-clip-text text-5xl font-extrabold tracking-tight text-transparent md:text-6xl">
                            NEXUS-CORE
                        </h1>

                        <p className="mx-auto mt-3 max-w-2xl text-base text-slate-400 md:text-lg">
                            Erstelle Avatare mit Hintergrund, Verlauf, Outline, Schatten und drehbarem Text.
                        </p>
                    </header>

                    <section className="mx-auto grid max-w-7xl gap-10 lg:grid-cols-[1fr_520px]">
                        <section aria-labelledby="controls-title" className="space-y-8">
                            <h2 id="controls-title" className="sr-only">
                                Editor-Steuerung
                            </h2>

                            <BackgroundPanel
                                selectedImage={ selectedImage }
                                setSelectedImage={ setSelectedImage }
                                customBg={ customBg }
                                setCustomBg={ setCustomBg }
                                customImage={ customImage }
                                setCustomImage={ setCustomImage }
                                isLogoT={ isLogoT }
                                fileInputRef={ fileInputRef }
                                fileKey={ fileKey }
                                handleFileUpload={ handleFileUpload }
                                resetFileInput={ () => setFileKey( ( k ) => k + 1 ) }
                            />

                            <TextPanel
                                text={ text }
                                setText={ setText }
                                textColor={ textColor }
                                setTextColor={ setTextColor }
                                font={ font }
                                setFont={ setFont }
                                fontSize={ fontSize }
                                setFontSize={ setFontSize }
                                recentFonts={ recentFonts }
                                setRecentFonts={ setRecentFonts }
                                textRotation={ textRotation }
                                setTextRotation={ setTextRotation }
                            />

                            <EffectsPanel
                                useGradient={ useGradient }
                                setUseGradient={ setUseGradient }
                                gradientType={ gradientType }
                                setGradientType={ setGradientType }
                                gradColor1={ gradColor1 }
                                setGradColor1={ setGradColor1 }
                                gradColor2={ gradColor2 }
                                setGradColor2={ setGradColor2 }
                                gradAngle={ gradAngle }
                                setGradAngle={ setGradAngle }
                                gradRadius={ gradRadius }
                                setGradRadius={ setGradRadius }
                                useOutline={ useOutline }
                                setUseOutline={ setUseOutline }
                                outlineColor={ outlineColor }
                                setOutlineColor={ setOutlineColor }
                                outlineWidth={ outlineWidth }
                                setOutlineWidth={ setOutlineWidth }
                                useShadow={ useShadow }
                                setUseShadow={ setUseShadow }
                                shadowColor={ shadowColor }
                                setShadowColor={ setShadowColor }
                                shadowBlur={ shadowBlur }
                                setShadowBlur={ setShadowBlur }
                                shadowOffsetX={ shadowOffsetX }
                                setShadowOffsetX={ setShadowOffsetX }
                                shadowOffsetY={ shadowOffsetY }
                                setShadowOffsetY={ setShadowOffsetY }
                            />
                        </section>

                        <PreviewPanel
                            baseCanvasRef={ baseCanvasRef }
                            overlayCanvasRef={ overlayCanvasRef }
                            text={ text }
                            onPointerDown={ onPointerDown }
                            onPointerMove={ onPointerMove }
                            onPointerUp={ onPointerUp }
                            downloadAvatar={ downloadAvatar }
                        />
                    </section>
                </main>
            </div>

            <footer className="mx-auto max-w-7xl px-4 py-8 text-center text-xs text-slate-500">
                © NEXUS-CORE Community · Gaming Avatar Generator
            </footer>
        </div>
    );
}