"use client";

import { useState, useEffect } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  DragEndEvent,
} from "@dnd-kit/core";
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { PageHeader } from "@/components/shared/page-header";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { NativeSelect } from "@/components/ui/native-select";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import {
  gamificationApi,
  UILayoutConfig,
  WidgetConfig,
  WidgetType,
  WidgetLocation,
  WidgetSize,
} from "@/lib/api-client";
import {
  GripVertical,
  Plus,
  Save,
  Trash2,
  Eye,
  EyeOff,
  Settings2,
  Layout,
  Award,
  Star,
  Trophy,
  Medal,
  Smartphone,
} from "lucide-react";
import { toast } from "sonner";

const WIDGET_TYPES: { value: WidgetType; label: string; icon: React.ReactNode }[] = [
  { value: "badges", label: "Badges", icon: <Award className="h-4 w-4" /> },
  { value: "points", label: "Points", icon: <Star className="h-4 w-4" /> },
  { value: "roles", label: "Roles", icon: <Medal className="h-4 w-4" /> },
  { value: "leaderboard_rank", label: "Leaderboard Rank", icon: <Trophy className="h-4 w-4" /> },
];

const WIDGET_LOCATIONS: { value: WidgetLocation; label: string }[] = [
  { value: "profile_header", label: "Profile Header (under avatar)" },
  { value: "profile_card", label: "Profile Card (separate section)" },
  { value: "home_feed_top", label: "Home Feed Top" },
  { value: "home_card", label: "Home Card" },
  { value: "sidebar", label: "Sidebar" },
  { value: "hidden", label: "Hidden" },
];

const WIDGET_SIZES: { value: WidgetSize; label: string }[] = [
  { value: "small", label: "Small (icon only)" },
  { value: "medium", label: "Medium (standard)" },
  { value: "large", label: "Large (full featured)" },
];

interface SortableWidgetProps {
  widget: WidgetConfig;
  index: number;
  onUpdate: (index: number, updates: Partial<WidgetConfig>) => void;
  onRemove: (index: number) => void;
}

function SortableWidget({ widget, index, onUpdate, onRemove }: SortableWidgetProps) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: `widget-${index}` });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.5 : 1,
  };

  const widgetInfo = WIDGET_TYPES.find((w) => w.value === widget.widgetType);
  const locationInfo = WIDGET_LOCATIONS.find((l) => l.value === widget.location);

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={`border rounded-lg p-4 bg-background ${isDragging ? "shadow-lg ring-2 ring-primary" : ""}`}
    >
      <div className="flex items-start gap-4">
        <button
          {...attributes}
          {...listeners}
          className="mt-1 cursor-grab active:cursor-grabbing text-muted-foreground hover:text-foreground"
        >
          <GripVertical className="h-5 w-5" />
        </button>

        <div className="flex-1 space-y-4">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              {widgetInfo?.icon}
              <span className="font-medium">{widgetInfo?.label || widget.widgetType}</span>
              {!widget.isVisible && (
                <span className="text-xs bg-muted px-2 py-0.5 rounded">Hidden</span>
              )}
            </div>
            <div className="flex items-center gap-2">
              <Button
                variant="ghost"
                size="sm"
                onClick={() => onUpdate(index, { isVisible: !widget.isVisible })}
              >
                {widget.isVisible ? <Eye className="h-4 w-4" /> : <EyeOff className="h-4 w-4" />}
              </Button>
              <Button
                variant="ghost"
                size="sm"
                className="text-destructive hover:text-destructive"
                onClick={() => onRemove(index)}
              >
                <Trash2 className="h-4 w-4" />
              </Button>
            </div>
          </div>

          <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
            <div>
              <Label className="text-xs text-muted-foreground">Location</Label>
              <NativeSelect
                value={widget.location}
                onChange={(e) => onUpdate(index, { location: e.target.value as WidgetLocation })}
                options={WIDGET_LOCATIONS}
                className="mt-1"
              />
            </div>
            <div>
              <Label className="text-xs text-muted-foreground">Size</Label>
              <NativeSelect
                value={widget.size}
                onChange={(e) => onUpdate(index, { size: e.target.value as WidgetSize })}
                options={WIDGET_SIZES}
                className="mt-1"
              />
            </div>
            <div className="flex items-end gap-4">
              <div className="flex items-center gap-2">
                <Switch
                  id={`showLabel-${index}`}
                  checked={widget.showLabel}
                  onCheckedChange={(checked) => onUpdate(index, { showLabel: checked })}
                />
                <Label htmlFor={`showLabel-${index}`} className="text-xs">Show Label</Label>
              </div>
            </div>
            <div className="flex items-end gap-4">
              <div className="flex items-center gap-2">
                <Switch
                  id={`showCount-${index}`}
                  checked={widget.showCount}
                  onCheckedChange={(checked) => onUpdate(index, { showCount: checked })}
                />
                <Label htmlFor={`showCount-${index}`} className="text-xs">Show Count</Label>
              </div>
            </div>
          </div>

          {widget.widgetType === "badges" && (
            <div className="grid grid-cols-2 gap-4">
              <div>
                <Label className="text-xs text-muted-foreground">Max Items</Label>
                <Input
                  type="number"
                  min={1}
                  max={50}
                  value={widget.maxItems || ""}
                  onChange={(e) => onUpdate(index, { maxItems: parseInt(e.target.value) || undefined })}
                  placeholder="No limit"
                  className="mt-1"
                />
              </div>
              <div>
                <Label className="text-xs text-muted-foreground">Custom Label</Label>
                <Input
                  value={widget.customLabel || ""}
                  onChange={(e) => onUpdate(index, { customLabel: e.target.value || undefined })}
                  placeholder="Default label"
                  className="mt-1"
                />
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function PhonePreview({ widgets }: { widgets: WidgetConfig[] }) {
  const visibleWidgets = widgets.filter((w) => w.isVisible && w.location !== "hidden");
  const headerWidgets = visibleWidgets.filter((w) => w.location === "profile_header");
  const cardWidgets = visibleWidgets.filter((w) => w.location === "profile_card");

  const getWidgetIcon = (type: WidgetType) => {
    const info = WIDGET_TYPES.find((w) => w.value === type);
    return info?.icon || <Star className="h-4 w-4" />;
  };

  const getWidgetLabel = (widget: WidgetConfig) => {
    if (widget.customLabel) return widget.customLabel;
    const info = WIDGET_TYPES.find((w) => w.value === widget.widgetType);
    return info?.label || widget.widgetType;
  };

  return (
    <div className="w-64 mx-auto">
      <div className="border-4 border-gray-800 rounded-[2.5rem] bg-gray-800 p-1">
        <div className="bg-white rounded-[2rem] overflow-hidden h-[500px]">
          {/* Status bar */}
          <div className="h-6 bg-gray-100 flex items-center justify-center">
            <div className="w-20 h-4 bg-gray-800 rounded-full" />
          </div>

          {/* Profile section */}
          <div className="p-4">
            {/* Avatar */}
            <div className="flex flex-col items-center mb-4">
              <div className="w-20 h-20 rounded-full bg-gradient-to-br from-blue-400 to-purple-500 mb-2" />
              <div className="h-4 w-24 bg-gray-200 rounded mb-1" />
              <div className="h-3 w-16 bg-gray-100 rounded" />

              {/* Header widgets */}
              {headerWidgets.length > 0 && (
                <div className="flex items-center gap-3 mt-3">
                  {headerWidgets.map((widget, i) => (
                    <div
                      key={i}
                      className={`flex items-center gap-1 ${
                        widget.size === "small" ? "text-xs" : widget.size === "large" ? "text-base" : "text-sm"
                      }`}
                    >
                      {getWidgetIcon(widget.widgetType)}
                      {widget.showLabel && (
                        <span className="text-gray-600">{getWidgetLabel(widget)}</span>
                      )}
                      {widget.showCount && (
                        <span className="font-semibold text-gray-800">12</span>
                      )}
                    </div>
                  ))}
                </div>
              )}
            </div>

            {/* Card widgets */}
            {cardWidgets.map((widget, i) => (
              <div key={i} className="border rounded-lg p-3 mb-3 bg-gray-50">
                <div className="flex items-center gap-2 mb-2">
                  {getWidgetIcon(widget.widgetType)}
                  {widget.showLabel && (
                    <span className="font-medium text-sm">{getWidgetLabel(widget)}</span>
                  )}
                  {widget.showCount && (
                    <span className="ml-auto text-sm font-semibold">12</span>
                  )}
                </div>
                {widget.size !== "small" && (
                  <div className="flex gap-1">
                    {[1, 2, 3, 4].slice(0, widget.maxItems || 4).map((n) => (
                      <div
                        key={n}
                        className={`rounded ${
                          widget.size === "large" ? "w-10 h-10" : "w-8 h-8"
                        } bg-gradient-to-br from-yellow-400 to-orange-500`}
                      />
                    ))}
                  </div>
                )}
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

export default function LayoutEditorPage() {
  const queryClient = useQueryClient();
  const [selectedLayoutId, setSelectedLayoutId] = useState<string | null>(null);
  const [widgets, setWidgets] = useState<WidgetConfig[]>([]);
  const [layoutName, setLayoutName] = useState("");
  const [layoutKey, setLayoutKey] = useState("");
  const [layoutDescription, setLayoutDescription] = useState("");
  const [isDefault, setIsDefault] = useState(false);
  const [isActive, setIsActive] = useState(true);
  const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
  const [hasChanges, setHasChanges] = useState(false);

  const sensors = useSensors(
    useSensor(PointerSensor),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );

  const { data: layouts, isLoading } = useQuery({
    queryKey: ["ui-layouts"],
    queryFn: async () => {
      const response = await gamificationApi.getUILayouts();
      return response.data;
    },
  });

  const createMutation = useMutation({
    mutationFn: (data: { key: string; name: string; description?: string; widgets: WidgetConfig[]; isDefault?: boolean; isActive?: boolean }) =>
      gamificationApi.createUILayout(data),
    onSuccess: (response) => {
      queryClient.invalidateQueries({ queryKey: ["ui-layouts"] });
      setSelectedLayoutId(response.data.id);
      setIsCreateDialogOpen(false);
      toast.success("Layout created successfully");
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || "Failed to create layout");
    },
  });

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: string; data: { name?: string; description?: string; widgets?: WidgetConfig[]; isDefault?: boolean; isActive?: boolean } }) =>
      gamificationApi.updateUILayout(id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["ui-layouts"] });
      setHasChanges(false);
      toast.success("Layout saved successfully");
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || "Failed to save layout");
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (id: string) => gamificationApi.deleteUILayout(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["ui-layouts"] });
      setSelectedLayoutId(null);
      setWidgets([]);
      toast.success("Layout deleted");
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || "Failed to delete layout");
    },
  });

  // Load layout when selected
  useEffect(() => {
    if (selectedLayoutId && layouts) {
      const layout = layouts.find((l) => l.id === selectedLayoutId);
      if (layout) {
        setWidgets(layout.widgets);
        setLayoutName(layout.name);
        setLayoutKey(layout.key);
        setLayoutDescription(layout.description || "");
        setIsDefault(layout.isDefault);
        setIsActive(layout.isActive);
        setHasChanges(false);
      }
    }
  }, [selectedLayoutId, layouts]);

  // Auto-select first layout
  useEffect(() => {
    if (layouts && layouts.length > 0 && !selectedLayoutId) {
      setSelectedLayoutId(layouts[0].id);
    }
  }, [layouts, selectedLayoutId]);

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;
    if (over && active.id !== over.id) {
      const oldIndex = parseInt(active.id.toString().replace("widget-", ""));
      const newIndex = parseInt(over.id.toString().replace("widget-", ""));
      setWidgets((items) => {
        const newItems = arrayMove(items, oldIndex, newIndex);
        return newItems.map((item, i) => ({ ...item, order: i + 1 }));
      });
      setHasChanges(true);
    }
  };

  const handleWidgetUpdate = (index: number, updates: Partial<WidgetConfig>) => {
    setWidgets((items) =>
      items.map((item, i) => (i === index ? { ...item, ...updates } : item))
    );
    setHasChanges(true);
  };

  const handleWidgetRemove = (index: number) => {
    setWidgets((items) => items.filter((_, i) => i !== index));
    setHasChanges(true);
  };

  const handleAddWidget = (type: WidgetType) => {
    const newWidget: WidgetConfig = {
      widgetType: type,
      location: "profile_card",
      size: "medium",
      order: widgets.length + 1,
      isVisible: true,
      showLabel: true,
      showCount: true,
    };
    setWidgets((items) => [...items, newWidget]);
    setHasChanges(true);
  };

  const handleSave = () => {
    if (selectedLayoutId) {
      updateMutation.mutate({
        id: selectedLayoutId,
        data: {
          name: layoutName,
          description: layoutDescription || undefined,
          widgets,
          isDefault,
          isActive,
        },
      });
    }
  };

  const handleCreateLayout = () => {
    createMutation.mutate({
      key: layoutKey,
      name: layoutName,
      description: layoutDescription || undefined,
      widgets: [
        {
          widgetType: "points",
          location: "profile_header",
          size: "small",
          order: 1,
          isVisible: true,
          showLabel: true,
          showCount: true,
        },
        {
          widgetType: "badges",
          location: "profile_card",
          size: "medium",
          order: 2,
          isVisible: true,
          showLabel: true,
          showCount: true,
          maxItems: 6,
        },
      ],
      isDefault: false,
      isActive: true,
    });
  };

  const availableWidgetTypes = WIDGET_TYPES.filter(
    (wt) => !widgets.some((w) => w.widgetType === wt.value)
  );

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-64">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <PageHeader
        title="Layout Editor"
        description="Configure where badges, points, and roles appear in the mobile app"
      >
        <div className="flex items-center gap-2">
          <NativeSelect
            value={selectedLayoutId || ""}
            onChange={(e) => setSelectedLayoutId(e.target.value)}
            options={layouts?.map((l) => ({ value: l.id, label: l.name })) || []}
            className="w-48"
          />
          <Button variant="outline" onClick={() => {
            setLayoutName("");
            setLayoutKey("");
            setLayoutDescription("");
            setIsCreateDialogOpen(true);
          }}>
            <Plus className="h-4 w-4 mr-2" />
            New Layout
          </Button>
        </div>
      </PageHeader>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
        {/* Widget Configuration */}
        <div className="lg:col-span-2 space-y-6">
          <Card>
            <CardHeader>
              <div className="flex items-center justify-between">
                <div>
                  <CardTitle className="flex items-center gap-2">
                    <Settings2 className="h-5 w-5" />
                    Widget Configuration
                  </CardTitle>
                  <CardDescription>
                    Drag to reorder widgets. Configure visibility and display settings.
                  </CardDescription>
                </div>
                <div className="flex items-center gap-2">
                  {hasChanges && (
                    <span className="text-xs text-amber-600">Unsaved changes</span>
                  )}
                  <Button onClick={handleSave} disabled={!hasChanges || updateMutation.isPending}>
                    <Save className="h-4 w-4 mr-2" />
                    {updateMutation.isPending ? "Saving..." : "Save"}
                  </Button>
                </div>
              </div>
            </CardHeader>
            <CardContent>
              {widgets.length === 0 ? (
                <div className="text-center py-8 text-muted-foreground">
                  <Layout className="h-12 w-12 mx-auto mb-4 opacity-50" />
                  <p>No widgets configured. Add widgets below.</p>
                </div>
              ) : (
                <DndContext
                  sensors={sensors}
                  collisionDetection={closestCenter}
                  onDragEnd={handleDragEnd}
                >
                  <SortableContext
                    items={widgets.map((_, i) => `widget-${i}`)}
                    strategy={verticalListSortingStrategy}
                  >
                    <div className="space-y-3">
                      {widgets.map((widget, index) => (
                        <SortableWidget
                          key={`widget-${index}`}
                          widget={widget}
                          index={index}
                          onUpdate={handleWidgetUpdate}
                          onRemove={handleWidgetRemove}
                        />
                      ))}
                    </div>
                  </SortableContext>
                </DndContext>
              )}

              {availableWidgetTypes.length > 0 && (
                <div className="mt-6 pt-6 border-t">
                  <Label className="text-sm text-muted-foreground mb-3 block">Add Widget</Label>
                  <div className="flex flex-wrap gap-2">
                    {availableWidgetTypes.map((wt) => (
                      <Button
                        key={wt.value}
                        variant="outline"
                        size="sm"
                        onClick={() => handleAddWidget(wt.value)}
                      >
                        {wt.icon}
                        <span className="ml-2">{wt.label}</span>
                      </Button>
                    ))}
                  </div>
                </div>
              )}
            </CardContent>
          </Card>

          {/* Layout Settings */}
          <Card>
            <CardHeader>
              <CardTitle>Layout Settings</CardTitle>
            </CardHeader>
            <CardContent>
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <Label>Layout Name</Label>
                  <Input
                    value={layoutName}
                    onChange={(e) => {
                      setLayoutName(e.target.value);
                      setHasChanges(true);
                    }}
                    className="mt-1"
                  />
                </div>
                <div>
                  <Label>Description</Label>
                  <Input
                    value={layoutDescription}
                    onChange={(e) => {
                      setLayoutDescription(e.target.value);
                      setHasChanges(true);
                    }}
                    placeholder="Optional description"
                    className="mt-1"
                  />
                </div>
                <div className="flex items-center gap-4">
                  <div className="flex items-center gap-2">
                    <Switch
                      id="isDefault"
                      checked={isDefault}
                      onCheckedChange={(checked) => {
                        setIsDefault(checked);
                        setHasChanges(true);
                      }}
                    />
                    <Label htmlFor="isDefault">Default Layout</Label>
                  </div>
                  <div className="flex items-center gap-2">
                    <Switch
                      id="isActive"
                      checked={isActive}
                      onCheckedChange={(checked) => {
                        setIsActive(checked);
                        setHasChanges(true);
                      }}
                    />
                    <Label htmlFor="isActive">Active</Label>
                  </div>
                </div>
                {selectedLayoutId && !isDefault && (
                  <div className="flex justify-end">
                    <Button
                      variant="destructive"
                      size="sm"
                      onClick={() => deleteMutation.mutate(selectedLayoutId)}
                      disabled={deleteMutation.isPending}
                    >
                      <Trash2 className="h-4 w-4 mr-2" />
                      Delete Layout
                    </Button>
                  </div>
                )}
              </div>
            </CardContent>
          </Card>
        </div>

        {/* Preview */}
        <div className="space-y-6">
          <Card>
            <CardHeader>
              <CardTitle className="flex items-center gap-2">
                <Smartphone className="h-5 w-5" />
                Mobile Preview
              </CardTitle>
              <CardDescription>
                Preview how widgets will appear on the profile screen
              </CardDescription>
            </CardHeader>
            <CardContent>
              <PhonePreview widgets={widgets} />
            </CardContent>
          </Card>
        </div>
      </div>

      {/* Create Layout Dialog */}
      <Dialog open={isCreateDialogOpen} onOpenChange={setIsCreateDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Create New Layout</DialogTitle>
            <DialogDescription>
              Create a new layout configuration for the mobile app
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4 py-4">
            <div>
              <Label>Key (unique identifier)</Label>
              <Input
                value={layoutKey}
                onChange={(e) => setLayoutKey(e.target.value.toLowerCase().replace(/\s+/g, "_"))}
                placeholder="e.g., mobile_minimal"
                className="mt-1"
              />
            </div>
            <div>
              <Label>Name</Label>
              <Input
                value={layoutName}
                onChange={(e) => setLayoutName(e.target.value)}
                placeholder="e.g., Minimal Layout"
                className="mt-1"
              />
            </div>
            <div>
              <Label>Description</Label>
              <Input
                value={layoutDescription}
                onChange={(e) => setLayoutDescription(e.target.value)}
                placeholder="Optional description"
                className="mt-1"
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setIsCreateDialogOpen(false)}>
              Cancel
            </Button>
            <Button
              onClick={handleCreateLayout}
              disabled={!layoutKey || !layoutName || createMutation.isPending}
            >
              {createMutation.isPending ? "Creating..." : "Create Layout"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
