import { useCallback, useState } from "react";
import { PlusIcon, Pencil1Icon, TrashIcon, CopyIcon, Cross2Icon, ChevronDownIcon, ChevronRightIcon } from "@radix-ui/react-icons";
import * as Tooltip from "@radix-ui/react-tooltip";
import * as Switch from "@radix-ui/react-switch";
import * as Dialog from "@radix-ui/react-dialog";
import type { PriceScenario, LayoutLocation } from "@/types";
import { getLocationsMap } from "@/types";
import { useLayouts, useDeleteLayout, useDuplicateLayout, useActivateLayoutLocation, useLocations } from "@/hooks/useLayouts";
import { useToast } from "@/hooks/useToast";
import { useLayoutPersistStore } from "@/stores/layoutPersistStore";
import { useCanvasStore } from "@/stores/canvasStore";
import { getErrorMessage } from "@/utils/errorMessage";
import type { Layout, AvailableLocations } from "@/api/layouts";

interface LayoutItemProps {
  layout: Layout;
  locations: AvailableLocations;
  isCurrentLayout: boolean;
  onEdit: (layout: Layout) => void;
  onDelete: (layout: Layout) => void;
  onDuplicate: (layout: Layout) => void;
  onActivateLocation: (layout: Layout, location: LayoutLocation, active: boolean) => void;
}

function LayoutItem({ layout, locations, isCurrentLayout, onEdit, onDelete, onDuplicate, onActivateLocation }: LayoutItemProps) {
  const getLocationActive = (location: string): boolean => {
    return layout.activeLocations?.[location] ?? false;
  };

  // Get short label for location (first word only for compact display)
  const getShortLabel = (label: string): string => {
    return label.split(" ")[0];
  };

  return (
    <div
      className={`
        group flex flex-col gap-2 p-2 rounded-md border
        transition-colors duration-150
        ${isCurrentLayout ? "bg-primary/10 border-primary/30" : "bg-surface border-border hover:border-border-hover"}
      `}
    >
      {/* Layout name and actions row */}
      <div className="flex items-center gap-2">
        <span className="flex-1 text-sm truncate font-medium text-text">{layout.name}</span>

        {/* Action buttons */}
        <div className="flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
          <Tooltip.Root>
            <Tooltip.Trigger asChild>
              <button onClick={() => onEdit(layout)} className="p-1 rounded hover:bg-surface-secondary text-text-muted hover:text-primary">
                <Pencil1Icon className="w-3.5 h-3.5" />
              </button>
            </Tooltip.Trigger>
            <Tooltip.Portal>
              <Tooltip.Content className="px-2 py-1 text-xs bg-text text-white rounded shadow-lg z-50" sideOffset={5}>
                Edit
                <Tooltip.Arrow className="fill-text" />
              </Tooltip.Content>
            </Tooltip.Portal>
          </Tooltip.Root>

          <Tooltip.Root>
            <Tooltip.Trigger asChild>
              <button
                onClick={() => onDuplicate(layout)}
                className="p-1 rounded hover:bg-surface-secondary text-text-muted hover:text-text"
              >
                <CopyIcon className="w-3.5 h-3.5" />
              </button>
            </Tooltip.Trigger>
            <Tooltip.Portal>
              <Tooltip.Content className="px-2 py-1 text-xs bg-text text-white rounded shadow-lg z-50" sideOffset={5}>
                Duplicate
                <Tooltip.Arrow className="fill-text" />
              </Tooltip.Content>
            </Tooltip.Portal>
          </Tooltip.Root>

          <Tooltip.Root>
            <Tooltip.Trigger asChild>
              <button onClick={() => onDelete(layout)} className="p-1 rounded hover:bg-danger/10 text-text-muted hover:text-error">
                <TrashIcon className="w-3.5 h-3.5" />
              </button>
            </Tooltip.Trigger>
            <Tooltip.Portal>
              <Tooltip.Content className="px-2 py-1 text-xs bg-text text-white rounded shadow-lg z-50" sideOffset={5}>
                Delete
                <Tooltip.Arrow className="fill-text" />
              </Tooltip.Content>
            </Tooltip.Portal>
          </Tooltip.Root>
        </div>
      </div>

      {/* Location toggles row */}
      {Object.keys(locations).length > 0 && (
        <div className="flex items-center gap-3 pt-1 border-t border-border flex-wrap">
          {Object.entries(locations).map(([locationKey, locationLabel]) => (
            <label key={locationKey} className="flex items-center gap-1.5 text-xs text-text-muted cursor-pointer">
              <Switch.Root
                className="w-7 h-4 bg-surface-secondary rounded-full relative data-[state=checked]:bg-primary outline-none"
                checked={getLocationActive(locationKey)}
                onCheckedChange={(checked) => onActivateLocation(layout, locationKey, checked)}
              >
                <Switch.Thumb className="block w-3 h-3 bg-white rounded-full transition-transform duration-100 translate-x-0.5 will-change-transform data-[state=checked]:translate-x-3.5" />
              </Switch.Root>
              <span>{getShortLabel(locationLabel)}</span>
            </label>
          ))}
        </div>
      )}
    </div>
  );
}

interface LayoutsPanelProps {
  scenario: PriceScenario;
  currentLayoutId: number | null;
  onEditLayout: (layout: Layout) => void;
  onNewLayout: () => void;
}

export function LayoutsPanel({ scenario, currentLayoutId, onEditLayout, onNewLayout }: LayoutsPanelProps) {
  // Persist collapsed state
  const isCollapsed = useLayoutPersistStore((state) => state.sidebarCollapsed.layouts);
  const toggleSection = useLayoutPersistStore((state) => state.toggleSidebarSection);
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [layoutToDelete, setLayoutToDelete] = useState<Layout | null>(null);
  const toast = useToast();

  // Fetch locations from API, fallback to PHP-provided defaults
  const { data: apiLocations } = useLocations();
  const locations: AvailableLocations = apiLocations && Object.keys(apiLocations).length > 0 ? apiLocations : getLocationsMap();

  // Fetch layouts for current scenario
  const { data: layoutsData, isLoading } = useLayouts({
    scenario,
    perPage: 50,
    orderby: "updated_at",
    order: "DESC",
  });

  const deleteLayoutMutation = useDeleteLayout({
    onSuccess: () => {
      setDeleteDialogOpen(false);
      const deletedName = layoutToDelete?.name ?? "Layout";
      setLayoutToDelete(null);
      toast.success("Layout deleted", { description: `"${deletedName}" was removed.` });
    },
    onError: (error) => {
      toast.error("Failed to delete layout", { description: getErrorMessage(error) });
    },
  });

  const duplicateLayoutMutation = useDuplicateLayout({
    onSuccess: (layout) => {
      toast.success("Layout duplicated", { description: `"${layout.name}" was created.` });
    },
    onError: (error) => {
      toast.error("Failed to duplicate layout", { description: getErrorMessage(error) });
    },
  });

  const activateLocationMutation = useActivateLayoutLocation({
    onError: (error) => {
      toast.error("Failed to update location", { description: getErrorMessage(error) });
    },
  });

  const handleDelete = useCallback((layout: Layout) => {
    // Clear canvas selection to hide floating settings panel before showing delete modal
    useCanvasStore.getState().clearSelection();
    setLayoutToDelete(layout);
    setDeleteDialogOpen(true);
  }, []);

  const handleConfirmDelete = useCallback(() => {
    if (layoutToDelete) {
      deleteLayoutMutation.mutate(layoutToDelete.id);
    }
  }, [layoutToDelete, deleteLayoutMutation]);

  const handleDuplicate = useCallback(
    (layout: Layout) => {
      duplicateLayoutMutation.mutate(layout.id);
    },
    [duplicateLayoutMutation]
  );

  const handleActivateLocation = useCallback(
    (layout: Layout, location: LayoutLocation, active: boolean) => {
      activateLocationMutation.mutate({
        id: layout.id,
        location,
        active,
      });
    },
    [activateLocationMutation]
  );

  const layouts = layoutsData?.data ?? [];

  return (
    <Tooltip.Provider delayDuration={300}>
      <div className="flex flex-col bg-surface border-l border-border">
        {/* Header */}
        <div className="flex items-center justify-between px-3 py-3 border-b border-border">
          <h3 className="text-sm font-semibold text-text">Layouts</h3>
          <div className="flex items-center gap-1">
            {/* Add new layout button */}
            <Tooltip.Root>
              <Tooltip.Trigger asChild>
                <button onClick={onNewLayout} className="p-1 text-text-muted hover:text-primary rounded hover:bg-surface-secondary">
                  <PlusIcon className="w-4 h-4" />
                </button>
              </Tooltip.Trigger>
              <Tooltip.Portal>
                <Tooltip.Content className="px-2 py-1 text-xs bg-text text-white rounded shadow-lg z-50" sideOffset={5}>
                  New Layout
                  <Tooltip.Arrow className="fill-text" />
                </Tooltip.Content>
              </Tooltip.Portal>
            </Tooltip.Root>

            {/* Collapse toggle */}
            <button
              onClick={() => toggleSection("layouts")}
              className="p-1 text-text-muted hover:text-text rounded hover:bg-surface-secondary"
            >
              {isCollapsed ? <ChevronRightIcon className="w-4 h-4" /> : <ChevronDownIcon className="w-4 h-4" />}
            </button>
          </div>
        </div>

        {/* Layouts list */}
        {!isCollapsed && (
          <div className="flex-1 overflow-y-auto p-2 max-h-48">
            {isLoading ? (
              <div className="flex items-center justify-center py-4">
                <div className="w-5 h-5 border-2 border-primary border-t-transparent rounded-full animate-spin" />
              </div>
            ) : layouts.length === 0 ? (
              <div className="flex flex-col items-center justify-center py-4 text-text-muted">
                <p className="text-sm">No layouts yet</p>
                <button onClick={onNewLayout} className="mt-2 text-xs text-primary hover:underline">
                  Create your first layout
                </button>
              </div>
            ) : (
              <div className="flex flex-col gap-2">
                {layouts.map((layout) => (
                  <LayoutItem
                    key={layout.id}
                    layout={layout}
                    locations={locations}
                    isCurrentLayout={layout.id === currentLayoutId}
                    onEdit={onEditLayout}
                    onDelete={handleDelete}
                    onDuplicate={handleDuplicate}
                    onActivateLocation={handleActivateLocation}
                  />
                ))}
              </div>
            )}
          </div>
        )}

        {/* Footer with count */}
        {!isCollapsed && layouts.length > 0 && (
          <div className="px-3 py-2 border-t border-border">
            <p className="text-xs text-text-muted">
              {layouts.length} layout{layouts.length !== 1 ? "s" : ""}
            </p>
          </div>
        )}
      </div>

      {/* Delete confirmation dialog */}
      <Dialog.Root open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
        <Dialog.Portal>
          <Dialog.Overlay className="fixed inset-0 bg-black/50 z-50" />
          <Dialog.Content className="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-surface rounded-lg shadow-xl p-6 w-[400px] z-50">
            <Dialog.Title className="text-lg font-semibold text-text mb-2">Delete Layout</Dialog.Title>
            <Dialog.Description className="text-sm text-text-muted mb-4">
              Are you sure you want to delete "{layoutToDelete?.name}"? This action cannot be undone.
            </Dialog.Description>

            <div className="flex justify-end gap-2">
              <button
                onClick={() => setDeleteDialogOpen(false)}
                className="px-4 py-2 text-sm text-text-muted hover:text-text rounded-md hover:bg-surface-secondary"
              >
                Cancel
              </button>
              <button
                onClick={handleConfirmDelete}
                disabled={deleteLayoutMutation.isPending}
                className="px-4 py-2 text-sm text-white bg-danger hover:bg-danger/90 rounded-md disabled:opacity-50"
              >
                {deleteLayoutMutation.isPending ? "Deleting..." : "Delete"}
              </button>
            </div>

            <Dialog.Close asChild>
              <button className="absolute top-4 right-4 p-1 text-text-muted hover:text-text rounded" aria-label="Close">
                <Cross2Icon className="w-4 h-4" />
              </button>
            </Dialog.Close>
          </Dialog.Content>
        </Dialog.Portal>
      </Dialog.Root>
    </Tooltip.Provider>
  );
}
