import React, { useEffect, useMemo, useRef, useState } from "react";
import { Loader2, MessageSquare, GitBranch, Eye, Plus } from "lucide-react";
import { toast } from "sonner";
import { useTranslation } from "react-i18next";

import { Button } from "@/shared/common/ui/button";
import { Textarea } from "@/shared/common/ui/textarea";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/shared/common/ui/dialog";

import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/common/ui/select";

import {
  Tabs,
  TabsContent,
  TabsList,
  TabsTrigger,
} from "@/shared/common/ui/tabs";

import { useAssignTasks } from "../hooks/useAssignTasks";
import { useChildIncomingInstances } from "../hooks/useIncomingInstances";

import RemarkList from "@/record-management/common/RemarkList";
import { useQueryClient } from "@tanstack/react-query";
import { useChildOutgoingInstances } from "../hooks/useChildOutgoingInstances";

export interface AssignmentHistoryDto {
  createdAt: string;
  id: string;
  amharicCreatedAt: string;
  repliedAt: string | null;
  parentAssignmentId: string;
  assignerId: string;
  assigneeId: string;
  assigneePositionId: string;
  assigneePosition: {
    id: string;
    name: {
      am: string;
      en: string;
    };
  };
  assignee: {
    id: string;
    employee: {
      name: {
        am: string;
        en: string;
      };
    };
  };
  assigner: {
    id: string;
    employee: {
      id: string;
      name: {
        am: string;
        en: string;
      };
    };
    delegator: {
      id: string;
      name?: {
        am?: string;
        en?: string;
      };
    } | null;
    position: {
      id: string;
      name: {
        am: string;
        en: string;
      };
    };
  };
}

export type InstanceType = "incoming" | "outgoing";

interface RemarkCreationDialogProps {
  open: boolean;
  onClose: () => void;
  incomingInstanceId: string;
  instanceType?: InstanceType;
  onSuccess?: () => void;
  rowData?: any;
}

const RemarkCreationDialog: React.FC<RemarkCreationDialogProps> = ({
  open,
  onClose,
  incomingInstanceId,
  instanceType = "incoming",
  onSuccess,
  rowData,
}) => {
  const { t, i18n } = useTranslation();
  const queryClient = useQueryClient();
  const [comment, setComment] = useState("");
  const [selectedPositionId, setSelectedPositionId] =
    useState(incomingInstanceId);
  const [activeTab, setActiveTab] = useState<"view" | "create">("view");

  const { addRemarkAsync, isAddingRemark } = useAssignTasks();

  const { data: incomingChildInstances, isLoading: isLoadingIncoming } =
    useChildIncomingInstances(incomingInstanceId, {
      enabled: open && !!incomingInstanceId && instanceType === "incoming",
    });

  const { data: outgoingChildInstances, isLoading: isLoadingOutgoing } =
    useChildOutgoingInstances(incomingInstanceId, {
      enabled: open && !!incomingInstanceId && instanceType === "outgoing",
    });

  const isLoadingInstances =
    instanceType === "incoming" ? isLoadingIncoming : isLoadingOutgoing;
  const childInstances = useMemo<AssignmentHistoryDto[]>(
    () =>
      instanceType === "incoming"
        ? (incomingChildInstances ?? [])
        : (outgoingChildInstances ?? []),
    [instanceType, incomingChildInstances, outgoingChildInstances],
  );

  // Build dropdown options:
  //   - Parent instances grouped by assigner.id (one entry per unique boss)
  //   - Child instances grouped by assigneePositionId (one entry per unique position)
  const instanceOptions = useMemo(() => {
    const options: Array<{
      value: string;
      label: string;
      instanceIds: string[];
      isParent?: boolean;
    }> = [];

    // Parent instances — grouped by assigner so all instances from the same boss collapse
    const assignerGrouped = new Map<
      string,
      { label: string; instanceIds: string[] }
    >();
    const parentInstances: Array<{
      id: string;
      assigner?: {
        id?: string;
        employee?: { name?: { am?: string; en?: string } };
      };
    }> = rowData?.incomingInstances ?? [];
    parentInstances.forEach((instance) => {
      const assignerId = instance.assigner?.id;
      if (!assignerId) return;
      const label =
        i18n.language === "am"
          ? instance.assigner?.employee?.name?.am
          : instance.assigner?.employee?.name?.en;

      if (assignerGrouped.has(assignerId)) {
        assignerGrouped.get(assignerId)!.instanceIds.push(instance.id);
      } else {
        assignerGrouped.set(assignerId, {
          label: label || assignerId,
          instanceIds: [instance.id],
        });
      }
    });
    assignerGrouped.forEach(({ label, instanceIds }, assignerId) => {
      options.push({ value: assignerId, label, instanceIds, isParent: true });
    });

    // Child instances — grouped by assigneePositionId; value = assigneePositionId
    const grouped = new Map<string, { label: string; instanceIds: string[] }>();
    childInstances.forEach((instance) => {
      const posId = instance.assigneePositionId;
      const label =
        i18n.language === "am"
          ? instance.assignee?.employee?.name?.am ||
            instance.assigneePosition?.name?.am
          : instance.assignee?.employee?.name?.en ||
            instance.assigneePosition?.name?.en;

      if (grouped.has(posId)) {
        grouped.get(posId)!.instanceIds.push(instance.id);
      } else {
        grouped.set(posId, {
          label: label || posId,
          instanceIds: [instance.id],
        });
      }
    });
    grouped.forEach(({ label, instanceIds }, posId) => {
      options.push({ value: posId, label, instanceIds });
    });

    return options;
  }, [childInstances, rowData, i18n.language]);

  // All instance IDs for the selected group — passed to RemarkList for merged viewing.
  // Also handles the case where selectedPositionId is a raw instance ID (not a group key)
  // by searching which group contains it.
  const selectedInstanceIds = useMemo(() => {
    const exact = instanceOptions.find((o) => o.value === selectedPositionId);
    if (exact) return exact.instanceIds;

    const containing = instanceOptions.find((o) =>
      o.instanceIds.includes(selectedPositionId),
    );
    return containing?.instanceIds ?? [incomingInstanceId];
  }, [selectedPositionId, instanceOptions, incomingInstanceId]);

  // Tracks whether we've already initialized selectedPositionId for the current
  // open session. Prevents child-instance async load from resetting user selection.
  const initializedRef = useRef(false);

  useEffect(() => {
    if (!open) {
      initializedRef.current = false;
      return;
    }
    if (initializedRef.current) return;

    const matchingOption = instanceOptions.find((o) =>
      o.instanceIds.includes(incomingInstanceId),
    );
    initializedRef.current = true;
    setSelectedPositionId(matchingOption?.value ?? incomingInstanceId);
    setActiveTab("view");
    setComment("");
  }, [open, incomingInstanceId, instanceOptions]);

  const handleSubmit = async () => {
    const trimmedComment = comment.trim();

    if (!trimmedComment) {
      toast.error(t("remark.commentRequired", "Comment cannot be empty."));
      return;
    }

    if (!selectedPositionId) {
      toast.error(t("remark.instanceRequired", "Please select an instance."));
      return;
    }

    const selectedOption = instanceOptions.find(
      (o) => o.value === selectedPositionId,
    );
    const targetIds = selectedOption?.instanceIds ?? [selectedPositionId];

    try {
      await Promise.all(
        targetIds.map((id) =>
          addRemarkAsync({ incomingInstanceId: id, comment: trimmedComment }),
        ),
      );

      targetIds.forEach((id) =>
        queryClient.invalidateQueries({ queryKey: ["incoming-remarks", id] }),
      );
      toast.success(t("remark.success", "Remark submitted successfully."));
      setComment("");
      setActiveTab("view");
      onSuccess?.();
    } catch {
      return;
    }
  };

  const handleClose = () => {
    setComment("");
    setSelectedPositionId(incomingInstanceId);
    setActiveTab("view");
    onClose();
  };

  return (
    <Dialog open={open} onOpenChange={(nextOpen) => !nextOpen && handleClose()}>
      <DialogContent className="sm:max-w-2xl h-[98dvh] max-h-[98dvh] flex flex-col p-4 sm:p-6 gap-4 sm:gap-6 overflow-hidden">
        <DialogHeader className="flex-shrink-0 text-left">
          <DialogTitle className="flex items-center gap-2">
            <div className="flex h-9 w-9 items-center justify-center rounded-xl bg-primary/10 text-primary">
              <MessageSquare className="h-4 w-4" />
            </div>
            {t("remark.title", "Remarks & Feedback")}
          </DialogTitle>
          <DialogDescription>
            {t(
              "remark.description",
              "View and add remarks for workflow instances",
            )}
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4 flex-1 flex flex-col min-h-0 overflow-hidden">
          {/* Instance Selection */}
          <div className="space-y-1.5 flex-shrink-0">
            <label className="text-sm font-medium">
              {t("remark.selectInstance", "Select Instance")}
            </label>

            <Select
              value={selectedPositionId}
              onValueChange={setSelectedPositionId}
              disabled={isAddingRemark || isLoadingInstances}>
              <SelectTrigger className="w-full">
                <SelectValue
                  placeholder={t(
                    "remark.selectInstancePlaceholder",
                    "Select an instance",
                  )}
                />
              </SelectTrigger>

              <SelectContent>
                {instanceOptions.map((option) => (
                  <SelectItem key={option.value} value={option.value}>
                    <div className="flex items-center gap-2">
                      <GitBranch className="h-4 w-4 text-muted-foreground" />
                      <span>{option.label}</span>
                      {option.isParent && (
                        <span className="ml-2 text-xs text-muted-foreground">
                          ({t("remark.current", "current")})
                        </span>
                      )}
                    </div>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {/* Tabs for View/Create Remarks */}
          <Tabs
            value={activeTab}
            onValueChange={(value) => setActiveTab(value as "view" | "create")}
            className="flex-1 flex flex-col min-h-0 overflow-hidden"
          >
            <TabsList className="grid w-full grid-cols-2 flex-shrink-0">
              <TabsTrigger value="view" className="flex items-center gap-2">
                <Eye className="h-4 w-4" />
                {t("remark.viewRemarks", "View Remarks")}
              </TabsTrigger>
              <TabsTrigger value="create" className="flex items-center gap-2">
                <Plus className="h-4 w-4" />
                {t("remark.createRemark", "Create Remark")}
              </TabsTrigger>
            </TabsList>

            <TabsContent
              value="view"
              className="mt-2 sm:mt-4 flex-1 flex flex-col min-h-0 overflow-hidden outline-none"
            >
              <div className="flex-1 pr-1 overflow-y-auto min-h-0">
                <RemarkList
                  instanceIds={selectedInstanceIds}
                  showFromText={false}
                />
              </div>
            </TabsContent>

            <TabsContent
              value="create"
              className="mt-2 sm:mt-4 flex-1 flex flex-col min-h-0 overflow-hidden outline-none space-y-4"
            >
              <div className="space-y-2 flex-1 flex flex-col min-h-0">
                <label className="text-sm font-medium">
                  {t("remark.remark", "Remark")}
                </label>

                <Textarea
                  value={comment}
                  onChange={(e) => setComment(e.target.value)}
                  placeholder={t("remark.placeholder", "Write your remark...")}
                  disabled={isAddingRemark}
                  className="flex-1 min-h-0 resize-none p-3 text-sm"
                />
              </div>
            </TabsContent>
          </Tabs>
        </div>

        <DialogFooter className="flex-shrink-0 mt-2 pt-3 border-t sm:mt-4 sm:pt-4">
          <Button
            type="button"
            variant="outline"
            onClick={handleClose}
            disabled={isAddingRemark}>
            {t("common.cancel", "Cancel")}
          </Button>

          {activeTab === "create" && (
            <Button
              type="button"
              onClick={handleSubmit}
              disabled={isAddingRemark}
              className="min-w-32">
              {isAddingRemark && (
                <Loader2 className="mr-2 h-4 w-4 animate-spin" />
              )}
              {t("remark.submit", "Submit Remark")}
            </Button>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
};

export default RemarkCreationDialog;
