import { useContext, useEffect, useState } from 'react'
import { Label } from '@/components/ui/label'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import ColorContext from './Context/colorContext/ColorContext'
import CanvasContext from './Context/canvasContext/CanvasContext'
import { fabric } from 'fabric'

const ColorComponent = () => {
    const { canvas } = useContext(CanvasContext)
    const { backgroundType, setBackgroundType, solidColor, gradientColors, setSolidColor, setGradientColors, gradientDirection, setGradientDirection, setDirectionCoords,
    } = useContext(ColorContext)

    const [previewBackgroundType, setPreviewBackgroundType] = useState(backgroundType)
    const [previewSolidColor, setPreviewSolidColor] = useState(solidColor)
    const [previewGradientColors, setPreviewGradientColors] = useState(gradientColors)
    const [previewGradientDirection, setPreviewGradientDirection] = useState(gradientDirection)

    useEffect(() => {
        setPreviewBackgroundType(backgroundType)
        setPreviewSolidColor(solidColor)
        setPreviewGradientColors(gradientColors)
        setPreviewGradientDirection(gradientDirection)
    }, [backgroundType, solidColor, gradientColors, gradientDirection])

    useEffect(() => {
        if (previewBackgroundType === "gradient" && canvas) {
            const width = canvas.width || 0
            const height = canvas.height || 0

            const linearCoords = {
                "top-to-bottom": { x1: 0, y1: 0, x2: 0, y2: height },
                "bottom-to-top": { x1: 0, y1: height, x2: 0, y2: 0 },
                "left-to-right": { x1: 0, y1: 0, x2: width, y2: 0 },
                "right-to-left": { x1: width, y1: 0, x2: 0, y2: 0 },
            }

            const coords = linearCoords[previewGradientDirection]
            if (coords) {
                setDirectionCoords(coords)
            }
        }
    }, [previewBackgroundType, previewGradientDirection, canvas, setDirectionCoords])

    const applyChanges = () => {
        setBackgroundType(previewBackgroundType)
        setSolidColor(previewSolidColor)
        setGradientColors(previewGradientColors)
        setGradientDirection(previewGradientDirection)
        applyToCanvas()
    }

    const applyToCanvas = () => {
        if (!canvas) return

        if (previewBackgroundType === "color") {
            canvas.backgroundColor = previewSolidColor
        } else if (previewBackgroundType === "gradient") {
            const width = canvas.width || 0
            const height = canvas.height || 0

            const linearCoords = {
                "top-to-bottom": { x1: 0, y1: 0, x2: 0, y2: height },
                "bottom-to-top": { x1: 0, y1: height, x2: 0, y2: 0 },
                "left-to-right": { x1: 0, y1: 0, x2: width, y2: 0 },
                "right-to-left": { x1: width, y1: 0, x2: 0, y2: 0 },
            }

            const coords = linearCoords[previewGradientDirection]
            if (coords) {
                setDirectionCoords(coords)
                const gradient = new fabric.Gradient({
                    type: "linear",
                    gradientUnits: "pixels",
                    coords: coords,
                    colorStops: [
                        { offset: 0, color: previewGradientColors.color1 },
                        { offset: 1, color: previewGradientColors.color2 },
                    ],
                })
                canvas.backgroundColor = gradient
            }
        } else if (previewBackgroundType === "radial") {
            const gradient = new fabric.Gradient({
                type: "radial",
                gradientUnits: "pixels",
                coords: {
                    x1: canvas.width / 2,
                    y1: canvas.height / 2,
                    r1: 0,
                    x2: canvas.width / 2,
                    y2: canvas.height / 2,
                    r2: Math.min(canvas.width, canvas.height) / 2,
                },
                colorStops: [
                    { offset: 0, color: previewGradientColors.color1 },
                    { offset: 1, color: previewGradientColors.color2 },
                ],
            })
            canvas.backgroundColor = gradient
        }

        canvas.renderAll()
    }

    const getPreviewStyle = () => {
        if (previewBackgroundType === "color") {
            return { backgroundColor: previewSolidColor }
        } else if (previewBackgroundType === "gradient") {
            const direction = {
                'top-to-bottom': '180deg',
                'bottom-to-top': '0deg',
                'left-to-right': '90deg',
                'right-to-left': '270deg'
            }[previewGradientDirection]
            return {
                backgroundImage: `linear-gradient(${direction}, ${previewGradientColors.color1}, ${previewGradientColors.color2})`
            }
        } else if (previewBackgroundType === "radial") {
            return {
                backgroundImage: `radial-gradient(circle, ${previewGradientColors.color1}, ${previewGradientColors.color2})`
            }
        }
    }

    return (
        <div className='flex flex-col gap-4 p-1'>
            <div className='flex flex-col gap-2'>
                <Label>Background Type:</Label>
                <Select value={previewBackgroundType} onValueChange={setPreviewBackgroundType}>
                    <SelectTrigger>
                        <SelectValue placeholder="Select background type" />
                    </SelectTrigger>
                    <SelectContent>
                        <SelectItem value="color">Solid Color</SelectItem>
                        <SelectItem value="gradient">Linear Gradient</SelectItem>
                        <SelectItem value="radial">Radial Gradient</SelectItem>
                    </SelectContent>
                </Select>
            </div>

            {previewBackgroundType === "color" ? (
                <div className='flex flex-col gap-2'>
                    <Label>Solid Color:</Label>
                    <Input
                        type="color"
                        value={previewSolidColor}
                        onChange={(e) => setPreviewSolidColor(e.target.value)}
                    />
                </div>
            ) : previewBackgroundType === "gradient" ? (
                <div className='grid grid-cols-1 gap-2'>
                    <div className='flex flex-col gap-2'>
                        <Label>Direction:</Label>
                        <Select
                            value={previewGradientDirection}
                            onValueChange={setPreviewGradientDirection}
                        >
                            <SelectTrigger>
                                <SelectValue placeholder="Select direction" />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value="top-to-bottom">Top to Bottom</SelectItem>
                                <SelectItem value="bottom-to-top">Bottom to Top</SelectItem>
                                <SelectItem value="left-to-right">Left to Right</SelectItem>
                                <SelectItem value="right-to-left">Right to Left</SelectItem>
                            </SelectContent>
                        </Select>
                    </div>

                    <div className='flex flex-col gap-2'>
                        <Label>Color 1:</Label>
                        <Input
                            type="color"
                            value={previewGradientColors.color1}
                            onChange={(e) =>
                                setPreviewGradientColors((prev) => ({
                                    ...prev,
                                    color1: e.target.value,
                                }))}
                        />
                    </div>

                    <div className='flex flex-col gap-2'>
                        <Label>Color 2:</Label>
                        <Input
                            type="color"
                            value={previewGradientColors.color2}
                            onChange={(e) =>
                                setPreviewGradientColors((prev) => ({
                                    ...prev,
                                    color2: e.target.value,
                                }))}
                        />
                    </div>
                </div>
            ) : (
                <div className='grid grid-cols-1 gap-2'>
                    <div className='flex flex-col gap-2'>
                        <Label>Color 1:</Label>
                        <Input
                            type="color"
                            value={previewGradientColors.color1}
                            onChange={(e) =>
                                setPreviewGradientColors((prev) => ({
                                    ...prev,
                                    color1: e.target.value,
                                }))}
                        />
                    </div>

                    <div className='flex flex-col gap-2'>
                        <Label>Color 2:</Label>
                        <Input
                            type="color"
                            value={previewGradientColors.color2}
                            onChange={(e) =>
                                setPreviewGradientColors((prev) => ({
                                    ...prev,
                                    color2: e.target.value,
                                }))}
                        />
                    </div>
                </div>
            )}

            <div>
                <Label>Preview:</Label>
                <div
                    className='w-full h-24 rounded-md mt-2'
                    style={getPreviewStyle()}
                ></div>
            </div>

            <Button onClick={applyChanges}>
                Apply Changes
            </Button>
        </div>
    )
}

export default ColorComponent

