import React, { useEffect, useState } from "react";
import {
    useWebhookSetting,
    useCreateWebhookSetting,
    useUpdateWebhookSetting,
    useWebhooks,
} from "../../../utils/queries/webhook-queries";

import {
    useCreateWebhook,
    useUpdateWebhook,
    useDeleteWebhook,
} from "../../../utils/queries/webhook-queries";
import {useUpdatePathSetting} from "../../../utils/queries/path-setting-queries";
import { Plus, Save, Pencil, Trash2, Check } from "lucide-react";
import { Button } from "../../ui/button";
import { Input, Label } from "../../ui/input";
import { Spinner } from "../../ui/misc";

const SELECT_CLASS =
    "flex h-9 w-full rounded-md border border-input bg-background/60 px-3 py-1 text-sm text-foreground transition-colors focus-visible:outline-none focus-visible:border-primary/60 focus-visible:ring-2 focus-visible:ring-ring/40";

const CheckboxRow = ({ checked, onChange, label }) => (
    <label className="flex cursor-pointer items-center gap-2 text-sm text-foreground">
        <input
            type="checkbox"
            className="h-4 w-4 accent-primary"
            checked={checked}
            onChange={onChange}
        />
        {label}
    </label>
);

const WebhookSettingPanel = ({pathSetting, onClose}) => {

    const {data: setting} = useWebhookSetting(pathSetting?.webhook_setting_id || 0);
    const {data: webhooks, isLoading: isWebhooksLoading} = useWebhooks();

    const createWebhookSetting = useCreateWebhookSetting();
    const updateWebhookSetting = useUpdateWebhookSetting();

    const createWebhook = useCreateWebhook();
    const updateWebhook = useUpdateWebhook();
    const deleteWebhook = useDeleteWebhook();

    const updatePathSetting = useUpdatePathSetting();


    const [enabled, setEnabled] = useState(false);
    const [isRecursive, setIsRecursive] = useState(false);
    const [onEvents, setOnEvents] = useState(0);
    const [selectedUrl, setSelectedUrl] = useState("");
    const [headerList, setHeaderList] = useState([]);
    const [additionalHeaders, setAdditionalHeaders] = useState({});

    const [isOnMarkdownCreated, setIsOnMarkdownCreated] = useState(false);
    const [isOnMarkdownUpdated, setIsOnMarkdownUpdated] = useState(false);
    const [isOnMarkdownDeleted, setIsOnMarkdownDeleted] = useState(false);
    const [isOnPathCreated, setIsOnPathCreated] = useState(false);
    const [isOnPathUpdated, setIsOnPathUpdated] = useState(false);
    const [isOnPathDeleted, setIsOnPathDeleted] = useState(false);

    const assignFromOnEvents = (bits) => {
        setIsOnMarkdownCreated(!!(bits & 1));
        setIsOnMarkdownUpdated(!!(bits & 2));
        setIsOnMarkdownDeleted(!!(bits & 4));
        setIsOnPathCreated(!!(bits & 8));
        setIsOnPathUpdated(!!(bits & 16));
        setIsOnPathDeleted(!!(bits & 32));
    };

    const handleTriggerEventsUpdate = (eventType, isChecked) => {
        setOnEvents((prev) => {
            let nextVal = prev;
            switch (eventType) {
                case "MARKDOWN_CREATED":
                    nextVal = isChecked ? nextVal | 1 : nextVal & ~1;
                    setIsOnMarkdownCreated(isChecked);
                    break;
                case "MARKDOWN_UPDATED":
                    nextVal = isChecked ? nextVal | 2 : nextVal & ~2;
                    setIsOnMarkdownUpdated(isChecked);
                    break;
                case "MARKDOWN_DELETED":
                    nextVal = isChecked ? nextVal | 4 : nextVal & ~4;
                    setIsOnMarkdownDeleted(isChecked);
                    break;
                case "PATH_CREATED":
                    nextVal = isChecked ? nextVal | 8 : nextVal & ~8;
                    setIsOnPathCreated(isChecked);
                    break;
                case "PATH_UPDATED":
                    nextVal = isChecked ? nextVal | 16 : nextVal & ~16;
                    setIsOnPathUpdated(isChecked);
                    break;
                case "PATH_DELETED":
                    nextVal = isChecked ? nextVal | 32 : nextVal & ~32;
                    setIsOnPathUpdated(isChecked);
                    break;
                default:
                    break;
            }
            return nextVal;
        });
    };

    const handleCreateWebhookSetting = () => {
        createWebhookSetting.mutate({}, {
            onSuccess: (data) => {
                updatePathSetting.mutate({
                    id: pathSetting.id,
                    data: {
                        webhook_setting_id: data.id
                    }
                });
            }
        });
    };

    useEffect(() => {
        if (setting && webhooks) {
            setEnabled(setting.enabled);
            setIsRecursive(setting.recursive);
            setOnEvents(setting.on_events);
            assignFromOnEvents(setting.on_events);

            try {
                const headers = setting.additional_header
                    ? JSON.parse(setting.additional_header)
                    : {};
                setAdditionalHeaders(headers);
                setHeaderList(
                    Object.entries(headers).map(([k, v]) => ({ key: k, value: v }))
                );
            } catch (err) {
                setAdditionalHeaders({});
                setHeaderList([]);
            }

            const found = webhooks.find((wh) => wh.id === setting.webhook_id);
            setSelectedUrl(found ? found.hook_url : "");
        } else {
            setEnabled(false);
            setIsRecursive(false);
            setOnEvents(0);
            assignFromOnEvents(0);
            setAdditionalHeaders({});
            setHeaderList([]);
            setSelectedUrl("");
        }
    }, [setting, webhooks]);

    const handleAddHeader = () => {
        setHeaderList([...headerList, { key: "", value: "" }]);
    };
    const handleHeaderChange = (index, field, val) => {
        const updated = [...headerList];
        updated[index][field] = val;
        setHeaderList(updated);
    };
    const handleApplyHeaders = () => {
        const out = {};
        headerList.forEach(({ key, value }) => {
            if (key.trim()) out[key] = value;
        });
        setAdditionalHeaders(out);
    };

    const handleCreateWebhook = () => {
        const newUrl = prompt("Enter the new webhook URL");
        if (!newUrl) return;
        createWebhook.mutate(newUrl, {
            onSuccess: () => alert("Created new Webhook successfully"),
            onError: () => alert("Failed to create new Webhook"),
        });
    };
    const handleUpdateWebhook = () => {
        if (!setting || !setting.webhook_id) {
            alert("No webhook selected. Must pick from dropdown first.");
            return;
        }
        const newUrl = prompt("Enter updated Webhook URL", selectedUrl);
        if (!newUrl) return;
        updateWebhook.mutate(
            { id: setting.webhook_id, data: { hook_url: newUrl } },
            {
                onSuccess: () => alert("Updated Webhook successfully"),
                onError: () => alert("Failed to update Webhook"),
            }
        );
    };
    const handleDeleteWebhook = () => {
        if (!setting || !setting.webhook_id) {
            alert("No webhook selected to delete");
            return;
        }
        if (!window.confirm("Are you sure?")) return;
        deleteWebhook.mutate(setting.webhook_id, {
            onSuccess: () => alert("Deleted Webhook successfully"),
            onError: () => alert("Failed to delete Webhook"),
        });
    };

    const handleSaveWebhookSetting = async () => {
        const hook = webhooks.find((wh) => wh.hook_url === selectedUrl);
        const payload = {
            webhook_id: hook? hook.id : null,
            recursive: isRecursive,
            additional_header: JSON.stringify(additionalHeaders),
            enabled,
            on_events: onEvents,

        };
        if(!setting || !setting.id){
            createWebhookSetting.mutate(payload, {
                onSuccess: (res) => {
                    updatePathSetting.mutate({id: pathSetting.id, data: {webhook_setting_id: res.id}},{
                        onSuccess: () => alert("Webhook setting successfully created"),
                        onError: () => alert("Failed to save Webhook"),
                    })
                },
                onError: () => alert("Failed to save Webhook"),
            });
        } else {
            updateWebhookSetting.mutate({id: setting.id, data: payload}, {
                onSuccess: () => alert("Updated Webhook successfully"),
                onError: () => alert("Failed to update Webhook"),
            });
        }
        onClose();
    };

    return setting ? (
        <div className="mt-4 space-y-5 rounded-lg border border-border bg-surface/40 p-5">
            <h4 className="font-mono text-sm font-semibold uppercase tracking-wide text-foreground">
                Webhook Setting
            </h4>
            <div className="space-y-2">
                <Label>Select or Create a Webhook</Label>
                <div className="flex items-center gap-2">
                    <div className="flex-1">
                        {isWebhooksLoading ? (
                            <Spinner label="Loading webhooks" />
                        ) : (
                            <select
                                className={SELECT_CLASS}
                                value={selectedUrl}
                                onChange={(e) => setSelectedUrl(e.target.value)}
                            >
                                <option value="">(none)</option>
                                {webhooks.map((hook) => (
                                    <option key={hook.id} value={hook.hook_url}>
                                        {hook.hook_url}
                                    </option>
                                ))}
                            </select>
                        )}
                    </div>
                    <Button
                        type="button"
                        onClick={handleCreateWebhook}
                    >
                        <Plus className="h-4 w-4" /> Add
                    </Button>
                </div>
                {setting?.webhook_id && (
                    <div className="flex flex-wrap gap-2 pt-1">
                        <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            onClick={handleUpdateWebhook}
                        >
                            <Pencil className="h-4 w-4" /> Update Webhook URL
                        </Button>
                        <Button
                            type="button"
                            variant="destructive"
                            size="sm"
                            onClick={handleDeleteWebhook}
                        >
                            <Trash2 className="h-4 w-4" /> Delete Webhook
                        </Button>
                    </div>
                )}
            </div>

            <CheckboxRow
                checked={enabled}
                onChange={(e) => setEnabled(e.target.checked)}
                label="Enabled"
            />

            <div className="space-y-2">
                <Label>On Events</Label>
                <div className="grid grid-cols-1 gap-3 rounded-md border border-border bg-background/40 p-4 sm:grid-cols-2">
                    <div className="space-y-2">
                        <CheckboxRow
                            checked={isOnMarkdownCreated}
                            onChange={(e) =>
                                handleTriggerEventsUpdate("MARKDOWN_CREATED", e.target.checked)
                            }
                            label="Markdown Created"
                        />
                        <CheckboxRow
                            checked={isOnMarkdownUpdated}
                            onChange={(e) =>
                                handleTriggerEventsUpdate("MARKDOWN_UPDATED", e.target.checked)
                            }
                            label="Markdown Updated"
                        />
                        <CheckboxRow
                            checked={isOnMarkdownDeleted}
                            onChange={(e) =>
                                handleTriggerEventsUpdate("MARKDOWN_DELETED", e.target.checked)
                            }
                            label="Markdown Deleted"
                        />
                    </div>
                    <div className="space-y-2">
                        <CheckboxRow
                            checked={isOnPathCreated}
                            onChange={(e) =>
                                handleTriggerEventsUpdate("PATH_CREATED", e.target.checked)
                            }
                            label="Path Created"
                        />
                        <CheckboxRow
                            checked={isOnPathUpdated}
                            onChange={(e) =>
                                handleTriggerEventsUpdate("PATH_UPDATED", e.target.checked)
                            }
                            label="Path Updated"
                        />
                        <CheckboxRow
                            checked={isOnPathDeleted}
                            onChange={(e) =>
                                handleTriggerEventsUpdate("PATH_DELETED", e.target.checked)
                            }
                            label="Path Deleted"
                        />
                    </div>
                </div>
            </div>

            <CheckboxRow
                checked={isRecursive}
                onChange={(e) => setIsRecursive(e.target.checked)}
                label="Recursive"
            />

            <div className="space-y-2">
                <Label>Additional Headers</Label>
                <div className="space-y-3 rounded-md border border-border bg-background/40 p-4">
                    {headerList.map((h, idx) => (
                        <div className="flex gap-2" key={idx}>
                            <Input
                                type="text"
                                placeholder="key"
                                value={h.key}
                                onChange={(e) => handleHeaderChange(idx, "key", e.target.value)}
                            />
                            <Input
                                type="text"
                                placeholder="value"
                                value={h.value}
                                onChange={(e) =>
                                    handleHeaderChange(idx, "value", e.target.value)
                                }
                            />
                        </div>
                    ))}
                    <div className="flex gap-2">
                        <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            onClick={handleAddHeader}
                        >
                            <Plus className="h-4 w-4" /> Header
                        </Button>
                        <Button
                            type="button"
                            size="sm"
                            onClick={handleApplyHeaders}
                        >
                            <Check className="h-4 w-4" /> Apply
                        </Button>
                    </div>
                </div>
            </div>

            <Button
                type="button"
                onClick={handleSaveWebhookSetting}
            >
                <Save className="h-4 w-4" /> Save Webhook Setting
            </Button>
        </div>
    ) : (
        <Button
            type="button"
            onClick={handleCreateWebhookSetting}
        >
            <Plus className="h-4 w-4" /> Create Webhook Setting
        </Button>
    );
}


export default WebhookSettingPanel