import { useState } from "react";
import {
  CalendarCheck,
  Handshake,
  Phone,
  Users,
  ClipboardList,
  Presentation,
  Calendar,
} from "lucide-react";
import { trpc } from "@/lib/trpc";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { EntitySidebar } from "@/components/EntitySidebar";
import { EntitySearchSelect, type EntityOption } from "@/components/EntitySearchSelect";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

// Activity types with icons
const activityTypes = [
  { value: "Call", label: "Call", icon: Phone },
  { value: "Meeting", label: "Meeting", icon: Users },
  { value: "Task", label: "Task", icon: ClipboardList },
  { value: "Demo", label: "Demo", icon: Presentation },
] as const;

type ActivityType = (typeof activityTypes)[number]["value"];

interface Deal {
  id?: number;
  name?: string;
}

interface ActivityDetailSheetProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  activityId?: number | null;
  dealId?: number | null;
  onSuccess?: () => void;
  layer?: number;
}

export function ActivityDetailSheet({
  open,
  onOpenChange,
  activityId,
  dealId,
  onSuccess,
  layer = 0,
}: ActivityDetailSheetProps) {
  const isCreateMode = !activityId;

  // Deal search state
  const [dealSearchQuery, setDealSearchQuery] = useState("");

  const { data: activity, isLoading } = trpc.activities.getById.useQuery(
    { id: activityId! },
    { enabled: !!activityId && open }
  );

  // Search deals
  const { data: dealSearchResults, isLoading: isSearchingDeals } = trpc.deals.search.useQuery(
    { query: dealSearchQuery, limit: 5 },
    { enabled: open }
  );

  // Get initial deal from activity data or from provided dealId
  const getInitialDeal = (): EntityOption | null => {
    if (isCreateMode) {
      // If dealId is provided for create mode, we need to look it up
      if (dealId) {
        const foundDeal = dealSearchResults?.find(d => d.id === dealId);
        if (foundDeal?.id && foundDeal?.name) {
          return { id: foundDeal.id, name: foundDeal.name };
        }
      }
      return null;
    }
    if (!activity?.deal?.[0]) return null;
    const deal = activity.deal[0] as Deal;
    if (!deal.id || !deal.name) return null;
    return { id: deal.id, name: deal.name };
  };

  // Use activity data as initial values
  const initialName = isCreateMode ? "" : (activity?.name || "");
  const initialType = isCreateMode ? undefined : (activity?.type as ActivityType | undefined);
  const initialPlannedAt = isCreateMode ? "" : (activity?.plannedAt ? formatDateTimeLocal(activity.plannedAt) : "");
  const initialDeal = getInitialDeal();

  const [name, setName] = useState("");
  const [type, setType] = useState<ActivityType | undefined>(undefined);
  const [plannedAt, setPlannedAt] = useState("");
  const [selectedDeal, setSelectedDeal] = useState<EntityOption | null>(null);
  const [isInitialized, setIsInitialized] = useState(false);

  // Initialize form when data loads or sheet opens
  if (open && !isLoading && !isInitialized) {
    setName(initialName);
    setType(initialType);
    setPlannedAt(initialPlannedAt);
    setSelectedDeal(initialDeal);
    setIsInitialized(true);
  }

  // Reset when sheet closes
  if (!open && isInitialized) {
    setIsInitialized(false);
  }

  // Check if deal changed
  const dealChanged = isCreateMode
    ? selectedDeal !== null
    : (selectedDeal?.id !== initialDeal?.id);

  const hasChanges = isCreateMode
    ? name.trim().length > 0 || type !== undefined || plannedAt !== "" || selectedDeal !== null
    : (name !== initialName || type !== initialType || plannedAt !== initialPlannedAt || dealChanged);

  // For create mode, both name and type are required
  const canSave = isCreateMode
    ? name.trim().length > 0 && type !== undefined
    : hasChanges;

  const createMutation = trpc.activities.create.useMutation({
    onSuccess: () => {
      onSuccess?.();
      onOpenChange(false);
    },
  });

  const updateMutation = trpc.activities.update.useMutation({
    onSuccess: () => {
      onSuccess?.();
      onOpenChange(false);
    },
  });

  const deleteMutation = trpc.activities.delete.useMutation({
    onSuccess: () => {
      onSuccess?.();
      onOpenChange(false);
    },
  });

  const handleSave = () => {
    if (isCreateMode) {
      if (name.trim() && type) {
        createMutation.mutate({
          name,
          type: type,
          plannedAt: plannedAt ? new Date(plannedAt).toISOString() : undefined,
          deal: selectedDeal ? [selectedDeal.id] : undefined,
        });
      }
    } else if (activityId && hasChanges) {
      updateMutation.mutate({
        id: activityId,
        name: name || undefined,
        type: type,
        plannedAt: plannedAt ? new Date(plannedAt).toISOString() : undefined,
      });
    }
  };

  const handleDelete = () => {
    if (activityId) {
      deleteMutation.mutate({ id: activityId });
    }
  };

  const isPending = createMutation.isPending || updateMutation.isPending;

  // Map deal search results to EntityOption format
  const dealOptions: EntityOption[] = (dealSearchResults || [])
    .filter((d): d is typeof d & { id: number; name: string } => d.id !== undefined && d.name !== undefined)
    .map((deal) => ({
      id: deal.id,
      name: deal.name,
    }));

  return (
    <EntitySidebar
      open={open}
      onOpenChange={onOpenChange}
      title={isCreateMode ? "New Activity" : "Activity Details"}
      description={isCreateMode ? "Create a new activity" : "View and edit activity information"}
      icon={<CalendarCheck className="h-5 w-5 text-primary" />}
      isCreateMode={isCreateMode}
      isLoading={isLoading}
      hasChanges={canSave}
      isPending={isPending}
      isDeletePending={deleteMutation.isPending}
      onSave={handleSave}
      onDelete={isCreateMode ? undefined : handleDelete}
      layer={layer}
      footer={
        !isCreateMode && activity ? (
          <div className="pt-4 border-t">
            <p className="text-xs text-muted-foreground">
              Created: {activity.createdAt ? new Date(activity.createdAt).toLocaleDateString() : "-"}
              {activity.updatedAt && (
                <> | Updated: {new Date(activity.updatedAt).toLocaleDateString()}</>
              )}
            </p>
          </div>
        ) : undefined
      }
    >
      <div className="space-y-2">
        <Label htmlFor="name">Activity Name *</Label>
        <Input
          id="name"
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="e.g., Follow-up call with client"
        />
      </div>

      <div className="space-y-2">
        <Label htmlFor="type">Type *</Label>
        <Select
          value={type}
          onValueChange={(val) => setType(val as ActivityType)}
        >
          <SelectTrigger id="type">
            <SelectValue placeholder="Select activity type..." />
          </SelectTrigger>
          <SelectContent>
            {activityTypes.map((t) => {
              const Icon = t.icon;
              return (
                <SelectItem key={t.value} value={t.value}>
                  <span className="flex items-center gap-2">
                    <Icon className="h-4 w-4" />
                    {t.label}
                  </span>
                </SelectItem>
              );
            })}
          </SelectContent>
        </Select>
      </div>

      <div className="space-y-2">
        <Label htmlFor="plannedAt">Planned Date & Time</Label>
        <div className="relative">
          <Calendar className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
          <Input
            id="plannedAt"
            type="datetime-local"
            value={plannedAt}
            onChange={(e) => setPlannedAt(e.target.value)}
            className="pl-10"
          />
        </div>
      </div>

      <div className="space-y-2">
        <Label>Related Deal</Label>
        <EntitySearchSelect
          value={selectedDeal}
          onChange={setSelectedDeal}
          onSearch={setDealSearchQuery}
          onCreateNew={() => {}}
          options={dealOptions}
          isLoading={isSearchingDeals}
          placeholder="Select a deal..."
          icon={Handshake}
          entityName="Deal"
          disabled={!isCreateMode}
        />
        {!isCreateMode && (
          <p className="text-xs text-muted-foreground">
            Deal association cannot be changed after creation
          </p>
        )}
      </div>
    </EntitySidebar>
  );
}

// Helper function to format date for datetime-local input
function formatDateTimeLocal(isoDate: string): string {
  const date = new Date(isoDate);
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  const hours = String(date.getHours()).padStart(2, "0");
  const minutes = String(date.getMinutes()).padStart(2, "0");
  return `${year}-${month}-${day}T${hours}:${minutes}`;
}
