import React, { useState, useCallback, useEffect } from "react";
import {
  Accordion,
  AccordionItem,
  AccordionTrigger,
  AccordionContent,
} from "@/shared/common/ui/accordion";
import {
  Card,
  CardHeader,
  CardTitle,
  CardContent,
} from "@/shared/common/ui/card";
import { Badge } from "@/shared/common/ui/badge";
import {
  Clock,
  Users,
  UserCircle,
  ArrowRight,
  Split,
  ChevronDown,
  ArrowDown,
} from "lucide-react";
import { cn } from "@/shared/common/ui/fileUploader/utils";
import { renderStatus } from "@/record-management/utils/renderDetails";
import { useTranslation } from "react-i18next";
import { useLocalizedName } from "@/shared/common/localizedName";
import i18n from "@/i18n";
import MovementPdfExportButton from "./MovementPdfExportButton";
import type {
  AssignmentApiResponse,
  AssignmentMultipleUser,
  LocalizedText,
  AssignmentPosition,
} from "@/record-management/dto/AssignementStep";
import RemarkList from "@/record-management/common/RemarkList";

export interface AssignmentItem {
  type: "sequential" | "multiple";
  data: AssignmentApiResponse;
  date: number;
  id: string;
}

interface RecordAssignmentViewProps {
  recordId: string;
  recordTitle: string;
  recordType: string;
  subject: string;
  createdDate: string;
  referenceNumber?: string;
  assignmentChain: AssignmentApiResponse[];
  multipleAssignments: AssignmentApiResponse[];
  loading?: boolean;
}

const RecordAssignmentView: React.FC<RecordAssignmentViewProps> = ({
  recordId,
  recordTitle,
  recordType,
  subject,
  createdDate,
  referenceNumber,
  assignmentChain,
  multipleAssignments = [],
  loading = false,
}) => {
  const [expandedItems, setExpandedItems] = useState<string[]>([]);
  const { t } = useTranslation();
  const localizedName = useLocalizedName() as (
    value?: string | LocalizedText | null,
  ) => string;
  const lang = i18n.language;
  const isExternalOutgoing =
    recordType === "External" && referenceNumber?.includes("outgoing");

  const getLocalizedText = (value?: string | LocalizedText | null) => {
    if (!value) {
      return "";
    }

    return typeof value === "string" ? value : localizedName(value) || "";
  };

  const getAssigneeDisplayText = (assignee?: AssignmentPosition | null) => {
    if (!assignee) {
      return "Unknown";
    }
    if (isExternalOutgoing && assignee.role && assignee.department) {
      return `${assignee.role}, ${assignee.department}`;
    }
    if (typeof assignee.name === "object" && assignee.name !== null) {
      return getLocalizedText(assignee.name) || "Unknown";
    }
    return assignee.name || "Unknown";
  };

  const getAssetUrl = (
    asset?: { presigned?: string; url?: string | null } | null,
  ) => asset?.presigned || asset?.url || "";

  const renderRemarkSection = (assignment: AssignmentApiResponse) => {
    const signatureUrl = getAssetUrl(assignment.signature);
    const teeterUrl = getAssetUrl(assignment.teeter);
    const hasVisuals = Boolean(signatureUrl || teeterUrl);
    const hasComment = Boolean(assignment.comment);

    if (!hasVisuals && !hasComment) {
      return null;
    }

    return (
      <div className="p-3 bg-primary/5 rounded-lg border border-primary/20">
        <div className="flex flex-col gap-3 sm:flex-row sm:items-start">
          {hasVisuals && (
            <div className="flex shrink-0 flex-row gap-2 sm:w-28 sm:flex-col">
              {signatureUrl && (
                <img
                  src={signatureUrl}
                  alt="Signature"
                  className="h-20 w-20 rounded-md border border-border/50 bg-background object-contain p-1"
                />
              )}
              {teeterUrl && (
                <img
                  src={teeterUrl}
                  alt="Teeter"
                  className="h-20 w-20 rounded-md border border-border/50 bg-background object-contain p-1"
                />
              )}
            </div>
          )}

          {hasComment && (
            <p className="text-sm min-w-0">
              <span className="font-semibold text-foreground">
                {t("assignment.comment")}{" "}
              </span>
              <span className="text-muted-foreground">
                {assignment.comment}
              </span>
            </p>
          )}
        </div>
      </div>
    );
  };

  const getAllAssignmentsInOrder = useCallback((): AssignmentItem[] => {
    const flattenAssignments = (
      assignments: AssignmentApiResponse[],
      type: "sequential" | "multiple",
    ): AssignmentItem[] => {
      return assignments.flatMap((assignment) => {
        const baseItem = {
          type,
          data: assignment,
          date: new Date(assignment.createdAt).getTime(),
          id: assignment.id,
        };

        if (assignment.children && assignment.children.length > 0) {
          return [baseItem, ...flattenAssignments(assignment.children, type)];
        }
        return [baseItem];
      });
    };

    const sequentialAssignments = flattenAssignments(
      assignmentChain,
      "sequential",
    );
    const multipleAssignmentsFlattened = flattenAssignments(
      multipleAssignments,
      "multiple",
    );

    return [...sequentialAssignments, ...multipleAssignmentsFlattened].sort(
      (a, b) => a.date - b.date,
    );
  }, [assignmentChain, multipleAssignments]);

  const allAssignments = getAllAssignmentsInOrder();

  const rootAssignments = allAssignments.filter((item) => {
    return (
      !item.data.parentAssignmentId &&
      !item.data.parentId &&
      !item.data.previousStepId
    );
  });

  const assignmentMap = new Map<string, AssignmentItem[]>();
  allAssignments.forEach((item) => {
    const parentId =
      item.data.parentAssignmentId ||
      item.data.parentId ||
      item.data.previousStepId;
    if (parentId) {
      if (!assignmentMap.has(parentId)) {
        assignmentMap.set(parentId, []);
      }
      assignmentMap.get(parentId)!.push(item);
    }
  });
  const renderAssignmentTree = (item: AssignmentItem, index: number) => {
    const hasChildren = assignmentMap.has(item.id);
    const children = assignmentMap.get(item.id) || [];
    const isExpanded = expandedItems.includes(item.id);
    return (
      <AccordionItem
        value={item.id}
        key={item.id}
        className="rounded-lg mb-3 overflow-hidden border border-border/50 bg-card hover:border-border transition-all duration-200 hover:shadow-md">
        <AccordionTrigger className="py-4 px-5 border border-border rounded-md hover:no-underline hover:bg-primary/10 transition-colors">
          <div className="relative flex items-start gap-4 w-full pl-0">
            <div
              className={cn(
                "relative z-10 h-10 w-10 rounded-full flex items-center justify-center text-sm font-bold aspect-square flex-shrink-0 transition-all duration-300",
                item.type === "multiple"
                  ? "bg-gradient-to-br from-purple-500 to-purple-600 text-white shadow-lg"
                  : "bg-gradient-to-br from-primary-500 to-primary-600 text-white shadow-lg",
              )}>
              {item.type === "multiple" ? (
                <Split className="h-5 w-5" />
              ) : (
                <span>{index + 1}</span>
              )}
            </div>

            <div className="flex flex-col flex-1 min-w-0">
              <div className="flex items-center gap-3 flex-wrap">
                <span className="font-semibold text-foreground break-words whitespace-normal">
                  {item.type === "sequential" ? (
                    <>
                      {item.data.assignee?.employee ? (
                        <>
                          {item.data.assignee?.employee?.name && (
                            <span>
                              {getLocalizedText(
                                item.data.assignee.employee.name,
                              )}
                            </span>
                          )}
                          {item.data.assigneePosition && (
                            <span className="text-muted-foreground font-normal">
                              {" "}
                              •{" "}
                              {getAssigneeDisplayText(
                                item.data.assigneePosition,
                              )}
                            </span>
                          )}
                          {!item.data.assigneePosition?.name &&
                            !item.data.assignee?.employee?.name &&
                            "Unknown"}
                        </>
                      ) : (
                        <>
                          {item.data.assigneePosition && (
                            <span>
                              {getAssigneeDisplayText(
                                item.data.assigneePosition,
                              )}
                            </span>
                          )}
                          {!item.data.assigneePosition?.name && "Unknown"}
                        </>
                      )}
                    </>
                  ) : (
                    `Multiple Recipients (${
                      item.data.assignedToUsers?.length ?? 0
                    })`
                  )}
                </span>

                {item.type === "sequential" &&
                  (() => {
                    const formattedStatus = item.data.status
                      .split("_")
                      .map(
                        (word: string) =>
                          word.charAt(0).toUpperCase() + word.slice(1),
                      )
                      .join(" ");

                    return (
                      <span>
                        {renderStatus(formattedStatus, formattedStatus)}
                      </span>
                    );
                  })()}
              </div>

              <span className="text-xs text-muted-foreground mt-1 flex items-center gap-1">
                <Clock className="h-3 w-3" />
                {lang === "en"
                  ? (() => {
                      const date = item.data.createdAt;
                      return date
                        ? new Date(date).toLocaleString("en-US", {
                            year: "numeric",
                            month: "short",
                            day: "numeric",
                            hour: "2-digit",
                            minute: "2-digit",
                          })
                        : "—";
                    })()
                  : item.data.amharicCreatedAt || "—"}
              </span>

              {hasChildren && (
                <div className="mt-2 text-xs font-medium text-primary bg-primary/10 rounded-full px-2 py-1 inline-block w-fit">
                  +{children.length} {t("assignment.next")}
                </div>
              )}
            </div>
          </div>
        </AccordionTrigger>

        <AccordionContent className="px-5 py-4 bg-secondary/20 border-t border-border/30">
          <div className="space-y-5">
            {item.type === "sequential" ? (
              <>
                <div className="grid grid-cols-1 md:grid-cols-3 gap-4 items-start">
                  {/* Assigned By */}
                  <div className="flex flex-col gap-2 border border-gray-300 dark:border-gray-700 rounded-md p-3 dark:bg-gray-800">
                    <span className="text-xs font-semibold text-muted-foreground dark:text-gray-400 uppercase tracking-wide">
                      {t("assignment.assignedBy")}
                    </span>
                    <div className="flex items-start gap-3 p-3 bg-primary-50 dark:bg-primary-900/30 rounded-lg border border-primary-200 dark:border-primary-800">
                      <UserCircle className="h-5 w-5 text-primary dark:text-primary-400 flex-shrink-0 mt-0.5" />
                      <div className="min-w-0">
                        <p className="font-semibold text-sm text-foreground dark:text-gray-200">
                          {item.data.assigner?.employee?.name && (
                            <span className="block sm:inline">
                              {getLocalizedText(
                                item.data.assigner.employee.name,
                              )}
                            </span>
                          )}
                          {item.data.assigner?.position?.name && (
                            <span className="block sm:inline text-muted-foreground dark:text-gray-400 font-normal">
                              {" "}
                              •{" "}
                              {getLocalizedText(
                                item.data.assigner.position.name,
                              )}
                            </span>
                          )}
                          {!item.data.assigner?.position?.name &&
                            !item.data.assigner?.employee?.name &&
                            "Unknown"}
                        </p>
                      </div>
                    </div>
                  </div>

                  {/* Arrow */}
                  <div className="flex justify-center items-center md:pt-8">
                    {/* Mobile: Down arrow */}
                    <div className="flex md:hidden items-center gap-2 text-gray-700 dark:text-gray-300">
                      <ArrowDown className="h-5 w-5 text-gray-700 dark:text-gray-300" />
                    </div>

                    {/* Desktop: Right arrow */}
                    <div className="hidden md:flex items-center gap-2 text-gray-700 dark:text-gray-300">
                      <div className="h-px w-4 bg-gray-700 dark:bg-gray-400" />
                      <ArrowRight className="h-5 w-5 text-gray-700 dark:text-gray-300" />
                      <div className="h-px w-4 bg-gray-700 dark:bg-gray-400" />
                    </div>
                  </div>

                  {/* Assigned To */}
                  <div className="flex flex-col gap-2 border border-gray-300 dark:border-gray-700 rounded-md p-3 dark:bg-gray-800">
                    <span className="text-xs font-semibold text-muted-foreground dark:text-gray-400 uppercase tracking-wide">
                      {t("assignment.assignedTo")}
                    </span>
                    <div className="flex items-start gap-3 p-3 bg-primary-50 dark:bg-primary-900/30 rounded-lg border border-primary-200 dark:border-primary-800">
                      <UserCircle className="h-5 w-5 text-primary dark:text-primary-400 flex-shrink-0 mt-0.5" />
                      <div className="min-w-0">
                        {item.data.assignee?.employee ? (
                          <>
                            <p className="font-semibold text-sm text-foreground dark:text-gray-200">
                              {item.data.assignee?.employee?.name && (
                                <span className="block sm:inline">
                                  {getLocalizedText(
                                    item.data.assignee.employee.name,
                                  )}
                                </span>
                              )}
                              {item.data.assigneePosition && (
                                <span className="block sm:inline text-muted-foreground dark:text-gray-400 font-normal">
                                  {" "}
                                  •{" "}
                                  {getAssigneeDisplayText(
                                    item.data.assigneePosition,
                                  )}
                                </span>
                              )}
                              {!item.data.assigneePosition?.name &&
                                !item.data.assignee?.employee?.name &&
                                "Unknown"}
                            </p>
                          </>
                        ) : (
                          <>
                            <p className="font-semibold text-sm text-foreground dark:text-gray-200">
                              {item.data.assigneePosition && (
                                <span>
                                  {getAssigneeDisplayText(
                                    item.data.assigneePosition,
                                  )}
                                </span>
                              )}
                              {!item.data.assigneePosition?.name && "Unknown"}
                            </p>
                          </>
                        )}
                      </div>
                    </div>
                  </div>
                </div>

                {/* Metadata */}
                <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3 pt-2">
                  <div className="flex flex-col gap-1 p-3 bg-card rounded-lg border border-border/50">
                    <span className="text-xs text-muted-foreground font-medium">
                      {t("assignment.assignedOn")}
                    </span>
                    <span className="text-sm font-semibold text-foreground">
                      {lang === "en"
                        ? (() => {
                            const date = item.data.createdAt;
                            return date
                              ? new Date(date).toLocaleString("en-US", {
                                  year: "numeric",
                                  month: "short",
                                  day: "numeric",
                                  hour: "2-digit",
                                  minute: "2-digit",
                                })
                              : "—";
                          })()
                        : item.data.amharicCreatedAt || "—"}
                    </span>
                  </div>
                  <div className="flex flex-col gap-1 p-3 bg-card rounded-lg border border-border/50">
                    <span className="text-xs text-muted-foreground font-medium">
                      {t("assignment.assignedUsing")}
                    </span>
                    <span className="text-sm font-semibold text-foreground">
                      {item.data.assignee?.employee?.name
                        ? t("assignment.byName")
                        : t("assignment.byDepartment")}
                    </span>
                  </div>
                  {item.data.status !== "draft" && (
                    <div className="flex flex-col gap-1 p-3 bg-card rounded-lg border border-border/50">
                      <span className="text-xs text-muted-foreground font-medium">
                        {t(`statusBar.${item.data.status}`) +
                          " " +
                          t(`userRecord.Date`)}
                      </span>
                      <span className="text-sm font-semibold text-foreground">
                        {lang === "en"
                          ? (() => {
                              const date =
                                item.data.respondedAt ||
                                item.data.repliedAt ||
                                item.data.reassignAt;
                              return date
                                ? new Date(date).toLocaleString("en-US", {
                                    year: "numeric",
                                    month: "short",
                                    day: "numeric",
                                    hour: "2-digit",
                                    minute: "2-digit",
                                  })
                                : "—";
                            })()
                          : item.data.amharicRespondedAt ||
                            item.data.amharicRepliedAt ||
                            item.data.amharicReassignedAt ||
                            "—"}
                      </span>
                    </div>
                  )}
                </div>

                {renderRemarkSection(item.data)}
                <RemarkList instanceIds={[item.data.id]} />
              </>
            ) : (
              <>
                <div className="flex flex-col gap-2">
                  <span className="text-xs font-semibold text-muted-foreground dark:text-gray-400 uppercase tracking-wide">
                    {t("assignment.assignedBy")}
                  </span>
                  <div className="flex items-start gap-3 p-3 bg-card dark:bg-gray-800 rounded-lg border border-border/50 dark:border-gray-700">
                    <UserCircle className="h-5 w-5 text-primary dark:text-primary-400 flex-shrink-0 mt-0.5" />
                    <div className="min-w-0">
                      <p className="font-semibold text-sm text-foreground dark:text-gray-200">
                        {item.data.assigner?.employee?.name &&
                          getLocalizedText(item.data.assigner.employee.name)}
                        {item.data.assigner?.position?.name && (
                          <span className="text-muted-foreground dark:text-gray-400 font-normal">
                            {" "}
                            • {localizedName(item.data.assigner.position.name)}
                          </span>
                        )}
                        {!item.data.assigner?.position?.name &&
                          !item.data.assigner?.employee?.name &&
                          "Unknown"}
                      </p>
                    </div>
                  </div>
                </div>

                {/* Recipients Grid */}
                <div className="flex flex-col gap-2">
                  <span className="text-xs font-semibold text-muted-foreground dark:text-gray-400 uppercase tracking-wide">
                    {t("assignment.assignedTo")}
                  </span>
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                    {item.data.assignedToUsers?.map(
                      (user: AssignmentMultipleUser) => (
                        <div
                          key={user.id}
                          className="flex gap-3 p-3 bg-card rounded-lg border border-border/50 hover:border-primary transition-colors">
                          <UserCircle className="h-5 w-5 text-primary flex-shrink-0 mt-0.5" />
                          <div className="flex-1 min-w-0">
                            <div className="flex justify-between items-start gap-2 mb-1">
                              <p className="font-semibold text-sm text-foreground">
                                {isExternalOutgoing &&
                                user.role &&
                                user.department
                                  ? `${user.role}, ${user.department}`
                                  : localizedName(user.name)}
                              </p>
                              <span className="flex-shrink-0">
                                {renderStatus(
                                  user.status || "Unknown",
                                  user.status || "Unknown",
                                )}
                              </span>
                            </div>

                            {!isExternalOutgoing && user.department && (
                              <p className="text-xs text-muted-foreground mb-1">
                                {user.department}
                              </p>
                            )}

                            {user.completedDate && (
                              <p className="text-xs text-muted-foreground">
                                {t("assignment.responded")}{" "}
                                {new Date(
                                  user.completedDate,
                                ).toLocaleDateString()}
                              </p>
                            )}
                          </div>
                        </div>
                      ),
                    )}
                  </div>
                </div>

                {renderRemarkSection(item.data)}
              </>
            )}
          </div>

          {hasChildren && (
            <div className="mt-5 pt-5 border-t border-border/30">
              <div className="text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-3">
                {t("assignment.next")}
              </div>
              <div className="ml-4 pl-4 border-l-2 border-primary/30 space-y-3">
                <Accordion
                  type="multiple"
                  value={expandedItems}
                  onValueChange={setExpandedItems}>
                  {children.map((child, childIndex) =>
                    renderAssignmentTree(child, childIndex),
                  )}
                </Accordion>
              </div>
            </div>
          )}
        </AccordionContent>
      </AccordionItem>
    );
  };

  return (
    <div className="space-y-6 w-full">
      {(assignmentChain.length > 0 || multipleAssignments.length > 0) && (
        <Card className="border-border/50 shadow-lg">
          <CardHeader className="pb-4 border-b border-border/30">
            <div className="flex flex-col gap-4 md:flex-row md:items-start md:justify-between">
              <div className="flex items-center gap-3">
                <div className="h-10 w-10 rounded-lg bg-gradient-to-br from-primary-500 to-primary-600 flex items-center justify-center">
                  <Users className="h-5 w-5 text-white" />
                </div>
                <div>
                  <CardTitle className="text-2xl font-bold">
                    {t("assignment.assignmentFlow")}
                  </CardTitle>
                  <p className="text-sm text-muted-foreground mt-1">
                    {rootAssignments.length} {t("assignment.assInProg")}
                  </p>
                </div>
              </div>

              <div className="flex justify-start md:justify-end">
                <MovementPdfExportButton
                  recordTitle={recordTitle}
                  recordType={recordType}
                  subject={subject}
                  createdDate={createdDate}
                  referenceNumber={referenceNumber}
                  assignmentChain={assignmentChain}
                  multipleAssignments={multipleAssignments}
                  lang={lang}
                />
              </div>
            </div>
          </CardHeader>
          <CardContent className="pt-6">
            {loading ? (
              <div className="flex flex-col gap-4">
                {[1, 2, 3].map((i) => (
                  <div key={i} className="animate-pulse">
                    <div className="h-6 rounded w-1/4 mb-2 bg-muted"></div>
                    <div className="h-20 rounded w-full bg-muted"></div>
                  </div>
                ))}
              </div>
            ) : (
              <Accordion
                type="multiple"
                className="space-y-0"
                value={expandedItems}
                onValueChange={setExpandedItems}>
                {rootAssignments.map((assignment, index) =>
                  renderAssignmentTree(assignment, index),
                )}
              </Accordion>
            )}
          </CardContent>
        </Card>
      )}

      {!loading &&
        assignmentChain.length === 0 &&
        multipleAssignments.length === 0 && (
          <Card className="border-border/50 border-dashed">
            <CardContent className="py-12 text-center">
              <div className="flex justify-center mb-4">
                <div className="h-16 w-16 rounded-full bg-muted flex items-center justify-center">
                  <Users className="h-8 w-8 text-muted-foreground/60" />
                </div>
              </div>
              <p className="text-lg font-semibold text-foreground mb-2">
                {t("assignment.noAssignments")}
              </p>
              <p className="text-sm text-muted-foreground">{t("msg.noMsg")}</p>
            </CardContent>
          </Card>
        )}
    </div>
  );
};

export default RecordAssignmentView;
