import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { ImageIcon, Trash2 } from "lucide-react";
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from "@/shared/common/ui/select";
import { Button } from "@/shared/common/ui/button";
import {
  extractUrlFromListStyleImage,
  isCustomListStyleImage,
  isDisclosureListStyleImage,
  ListBulletResource,
  toResourceListStyleValue,
} from "../utils/templateResourceConstants";
import {
  STYLE_SELECT_CONTENT_CLASS,
  STYLE_SELECT_TRIGGER_CLASS,
} from "./styleSettingsUi";

interface ListStyleImageFieldProps {
  listStyleImage?: string;
  listStyle?: string;
  resourceId?: string | null;
  bulletResources: ListBulletResource[];
  bulletResourcesLoading: boolean;
  locale: "am" | "en";
  onReplace: (resourceId: string) => void;
  onRemove: () => void;
  onRefreshResources: () => Promise<unknown>;
}

const getResourceLabel = (
  resource: ListBulletResource,
  locale: "am" | "en",
) => resource.name?.[locale] || resource.name?.en || resource.id;

const DisclosurePreview = () => (
  <div className="flex h-full w-full items-center justify-center text-gray-700 dark:text-gray-200">
    <span className="text-lg leading-none" aria-hidden>
      ▶
    </span>
  </div>
);

export const ListStyleImageField: React.FC<ListStyleImageFieldProps> = ({
  listStyleImage,
  listStyle,
  resourceId,
  bulletResources,
  bulletResourcesLoading,
  locale,
  onReplace,
  onRemove,
  onRefreshResources,
}) => {
  const { t } = useTranslation();
  const [imageError, setImageError] = useState(false);
  const [isRefreshing, setIsRefreshing] = useState(false);

  const matchedResource = useMemo(() => {
    if (resourceId) {
      return bulletResources.find((resource) => resource.id === resourceId) ?? null;
    }

    if (!isCustomListStyleImage(listStyleImage)) return null;

    return (
      bulletResources.find(
        (resource) =>
          listStyleImage?.includes(resource.id) ||
          listStyleImage?.includes(resource.presigned) ||
          Boolean(
            resource.fileInfo?.fileName &&
              listStyleImage?.includes(resource.fileInfo.fileName),
          ),
      ) ?? null
    );
  }, [bulletResources, listStyleImage, resourceId]);

  const previewSrc = useMemo(() => {
    if (matchedResource?.presigned) {
      return matchedResource.presigned;
    }

    if (isDisclosureListStyleImage(listStyleImage)) {
      return extractUrlFromListStyleImage(listStyleImage);
    }

    if (listStyle?.split(" ")[0] === "disclosure-closed") {
      return extractUrlFromListStyleImage(listStyleImage) ?? null;
    }

    if (isCustomListStyleImage(listStyleImage)) {
      return extractUrlFromListStyleImage(listStyleImage);
    }

    return null;
  }, [listStyle, listStyleImage, matchedResource]);

  const hasImage = Boolean(
    matchedResource ||
      isCustomListStyleImage(listStyleImage) ||
      isDisclosureListStyleImage(listStyleImage) ||
      listStyle?.split(" ")[0] === "disclosure-closed",
  );

  useEffect(() => {
    setImageError(false);
  }, [previewSrc, matchedResource?.presigned]);

  const handleImageError = useCallback(async () => {
    if (isRefreshing || bulletResourcesLoading) return;

    setImageError(true);
    setIsRefreshing(true);
    try {
      await onRefreshResources();
    } finally {
      setIsRefreshing(false);
    }
  }, [bulletResourcesLoading, isRefreshing, onRefreshResources]);

  const selectedResourceValue = matchedResource
    ? toResourceListStyleValue(matchedResource.id)
    : undefined;

  return (
    <div className="space-y-2 rounded-lg border border-gray-200 bg-gray-50/80 p-3 dark:border-gray-600 dark:bg-gray-900/30">
      <label className="block text-xs font-medium text-gray-600 dark:text-gray-300">
        {t("template.listStyleImage", "List Style Image")}
      </label>

      <div className="flex flex-col gap-3 sm:flex-row sm:items-start">
        <div
          className="flex h-20 w-20 shrink-0 items-center justify-center overflow-hidden rounded-md border border-gray-200 bg-white dark:border-gray-600 dark:bg-gray-800"
          aria-label={t("template.listStyleImagePreview", "List style image preview")}
        >
          {previewSrc && !imageError ? (
            isDisclosureListStyleImage(listStyleImage) ||
            listStyle?.split(" ")[0] === "disclosure-closed" ? (
              <DisclosurePreview />
            ) : (
              <img
                src={previewSrc}
                alt=""
                className="h-full w-full object-contain p-1"
                onError={handleImageError}
              />
            )
          ) : imageError ? (
            <div className="px-2 text-center text-[10px] text-gray-500 dark:text-gray-400">
              {isRefreshing
                ? t("template.refreshingImage", "Refreshing...")
                : t("template.imageUnavailable", "Image unavailable")}
            </div>
          ) : (
            <div className="flex flex-col items-center gap-1 px-2 text-gray-400 dark:text-gray-500">
              <ImageIcon className="h-5 w-5" aria-hidden />
              <span className="text-[10px] text-center">
                {t("template.noListStyleImage", "No image")}
              </span>
            </div>
          )}
        </div>

        <div className="min-w-0 flex-1 space-y-2">
          {matchedResource && (
            <p className="text-xs text-gray-600 dark:text-gray-300">
              {getResourceLabel(matchedResource, locale)}
            </p>
          )}

          <Select
            value={selectedResourceValue}
            onValueChange={(value) => {
              const nextResourceId = value.slice("resource:".length);
              onReplace(nextResourceId);
            }}
            disabled={bulletResourcesLoading || bulletResources.length === 0}
          >
            <SelectTrigger className={STYLE_SELECT_TRIGGER_CLASS}>
              <SelectValue
                placeholder={t(
                  "template.replaceListStyleImage",
                  "Replace image",
                )}
              />
            </SelectTrigger>
            <SelectContent className={STYLE_SELECT_CONTENT_CLASS}>
              <SelectGroup>
                <SelectLabel>
                  {t(
                    "template.customListBullets",
                    "Custom bullets (Resource Configuration)",
                  )}
                </SelectLabel>
                {bulletResources.map((resource) => (
                  <SelectItem
                    key={resource.id}
                    value={toResourceListStyleValue(resource.id)}
                  >
                    <span className="flex min-w-0 items-center gap-2">
                      <img
                        src={resource.presigned}
                        alt=""
                        className="h-4 w-4 shrink-0 object-contain"
                      />
                      <span className="truncate">
                        {getResourceLabel(resource, locale)}
                      </span>
                    </span>
                  </SelectItem>
                ))}
              </SelectGroup>
            </SelectContent>
          </Select>

          {hasImage && (
            <Button
              type="button"
              variant="outline"
              size="sm"
              className="h-8 gap-1.5 text-xs"
              onClick={onRemove}
            >
              <Trash2 className="h-3.5 w-3.5" aria-hidden />
              {t("template.removeListStyleImage", "Remove image")}
            </Button>
          )}
        </div>
      </div>
    </div>
  );
};
