import { useState } from "react";
import { useMutation } from "@tanstack/react-query";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuTrigger,
} from "@/app/shadcn_components/ui/dropdown-menu";
import { Button } from "@/app/shadcn_components/ui/button";
import { Checkbox } from "@/app/shadcn_components/ui/checkbox";
import { Label } from "@/app/shadcn_components/ui/label";
import { GripVertical } from "lucide-react";
import { HelpCircle } from "lucide-react";
import { Loader2 } from "lucide-react";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/app/shadcn_components/ui/tooltip";

import {
  DndContext,
  closestCenter,
} from "@dnd-kit/core";
import {
  SortableContext,
  useSortable,
  verticalListSortingStrategy,
  arrayMove,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { ScenarioSummary } from "./types";

export interface RecommendationsOptionsProps {
  disabled?: boolean;
  scenarios: ScenarioSummary[]
  portfolioId: number
  onSuccess: () => void;
}

interface ScenarioWithPriority {
  id: number;
  priority: number; // 1 = highest, 2 = next, etc.
}

interface CategorisationTriggerRequest {
  portfolio_id: number;
  scenarios_to_consider?: number[] | null;
  scenario_priority_order?: number[] | null;
}

function mapScenariosToPayload(
  selectedScenarios: ScenarioWithPriority[],
  portfolio_id: number
): CategorisationTriggerRequest {
  if (!selectedScenarios || selectedScenarios.length === 0) {
    return {
      portfolio_id,
      scenarios_to_consider: null,
      scenario_priority_order: null,
    };
  }

  // Sort by priority just in case
  const sorted = [...selectedScenarios].sort((a, b) => a.priority - b.priority);

  return {
    portfolio_id,
    scenarios_to_consider: sorted.map((s) => s.id),
    scenario_priority_order: sorted.map((s) => s.id),
  };
}


function SortableScenarioItem({
  id,
  name,
  index,
}: {
  id: number;
  name: string;
  index: number;
}) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } =
    useSortable({ id });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  };

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={`flex items-center gap-2 p-2 border rounded bg-muted cursor-grab
        ${isDragging ? "opacity-70 scale-105 shadow-lg" : ""}
      `}
      {...attributes}
    >
      <GripVertical
        className="h-4 w-4 text-muted-foreground"
        {...listeners}
      />

      <span className="flex-1">{name}</span>

      <span className="text-xs text-muted-foreground">
        Priority {index + 1}
      </span>
    </div>
  );
}

function sendCategorisationRequest(selectedScenarios: ScenarioWithPriority[], portfolioId: number) {
  const payload = mapScenariosToPayload(selectedScenarios, portfolioId);
  return fetch("/api/plan/categorisation", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });
}

export function RecommendationsOptions({
  disabled = false,
  scenarios,
  portfolioId,
  onSuccess
}: RecommendationsOptionsProps) {
  const [isApplying, setIsApplying] = useState(false);
  const [open, setOpen] = useState(false);
  const [selectedScenarios, setSelectedScenarios] = useState<ScenarioWithPriority[]>([]);
  const [warning, setWarning] = useState<string | null>(null);

  const toggleScenario = (id: number) => {
    setWarning("")
    setSelectedScenarios((prev) => {
      const exists = prev.find((s) => s.id === id);
      if (exists) {
        // Remove
        return prev.filter((s) => s.id !== id);
      } else {
        // Add at the end with next priority
        return [...prev, { id, priority: prev.length + 1 }];
      }
    });
  };

  const handleSelectAll = () => {
    setWarning("")
    setSelectedScenarios(
      scenarios.map((s, index) => ({ id: s.id, priority: index + 1 }))
    );
  };

  const handleDeselectAll = () => {
    setWarning("")
    setSelectedScenarios([]);
  };

  const handleDragEnd = (event: any) => {
    const { active, over } = event;
    if (!over || active.id === over.id) return;

    setSelectedScenarios((items) => {
      const oldIndex = items.findIndex((s) => s.id === active.id);
      const newIndex = items.findIndex((s) => s.id === over.id);

      const newOrder = arrayMove(items, oldIndex, newIndex);

      // Update priority to match array index
      return newOrder.map((s, index) => ({ ...s, priority: index + 1 }));
    });
  };

  const { mutate, isPending } = useMutation({
  
  mutationFn: () => sendCategorisationRequest(selectedScenarios, portfolioId),
  // onSuccess: () => {
  // },
  // onError: () => {
  // }
});

const handleSubmit = () => {
  if (selectedScenarios.length === 1) {
    setWarning("Cannot generate recommendations for a single scenario");
    return;
  }
  setWarning(null);
  mutate();
  onSuccess();
  setOpen(false);
};

  const handleCancel = () => {
    setWarning("")
    setSelectedScenarios([]);
    setOpen(false);
  };

  const selectedScenarioObjects = selectedScenarios.map(
    (s) => ({
      ...scenarios.find((sc) => sc.id === s.id)!,
      priority: s.priority,
    })
  );

  return (
    <DropdownMenu open={open} onOpenChange={setOpen}>
      <DropdownMenuTrigger asChild>
        <Button
          variant="outline"
          size="sm"
          disabled={disabled || isApplying}
          className={`
            rounded-md px-3 py-2 text-sm font-medium transition
            ${
              disabled
                ? "bg-gray-200 text-gray-400 cursor-not-allowed"
                : "bg-brandblue text-white hover:bg-hoverblue"
            }
          `}
        >
          Calculate Recommended
        </Button>
      </DropdownMenuTrigger>

      <DropdownMenuContent className="w-80 p-4 space-y-4 max-h-[50vh] overflow-y-auto">
        <div className="flex justify-between">
          <Button size="sm" variant="ghost" onClick={handleSelectAll}>
            Select all
          </Button>
          <Button size="sm" variant="ghost" onClick={handleDeselectAll}>
            Deselect all
          </Button>
        </div>

        <div className="space-y-2">
          <h4 className="font-semibold">Select scenarios to consider</h4>

          {scenarios.map((scenario) => (
            <div key={scenario.id} className="flex items-center gap-2">
              <Checkbox
                checked={selectedScenarios.some((s) => s.id === scenario.id)}
                onCheckedChange={() => toggleScenario(scenario.id)}
              />
              <Label>{scenario.name}</Label>
            </div>
          ))}
        </div>

        {selectedScenarioObjects.length > 0 && (
          <div className="space-y-2">
            <div className="flex items-center gap-1">
              <h4 className="font-semibold">Drag to prioritise</h4>

              <TooltipProvider>
                <Tooltip>
                  <TooltipTrigger asChild>
                    <HelpCircle className="h-4 w-4 text-muted-foreground" />
                  </TooltipTrigger>
                  <TooltipContent>
                    <p>
                      This decides the order of selection if multiple scenarios have equal
                      outputs.
                    </p>
                  </TooltipContent>
                </Tooltip>
              </TooltipProvider>
            </div>

            <DndContext
              collisionDetection={closestCenter}
              onDragEnd={handleDragEnd}
            >
              <SortableContext
                items={selectedScenarios}
                strategy={verticalListSortingStrategy}
              >
                {selectedScenarioObjects.map((scenario, index) => (
                  <SortableScenarioItem
                    key={scenario.id}
                    id={scenario.id}
                    name={scenario.name}
                    index={index}
                  />
                ))}
              </SortableContext>
            </DndContext>
          </div>
        )}

        {warning && (
          <p className="text-sm text-red-600 font-medium">{warning}</p>
        )}

        <div className="flex justify-end gap-2 pt-2">
          <Button variant="ghost" size="sm" onClick={handleCancel}>
            Cancel
          </Button>
          <Button size="sm" onClick={handleSubmit} disabled={isApplying}>
            <span className="flex items-center gap-2">
              {isApplying && <Loader2 className="h-4 w-4 animate-spin" />}
              Submit
            </span>
          </Button>
        </div>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}