"use client";

import { useCallback, useEffect, useState } from "react";
import Image from "next/image";
import useAxios from "@/hooks/useAxios";
import { useUser } from "@/hooks/useUser";
import { Course, IAdvertising, IShopProductListing, Project } from "@/types/types";
import { cn } from "@/lib/utils";
import { IMAGE_BASE_URL } from "@/components/main/BaseUrl";
import { SelectedPostLink } from "@/lib/postLinkCaption";
import BoldIcon from "@/components/ui/BoldIcon";
import { useTranslation } from "react-i18next";

type MyShop = {
  _id: string;
  name: string;
  logo?: string | null;
};

interface PostLinkPickerProps {
  selectedPackages: SelectedPostLink[];
  selectedProjects: SelectedPostLink[];
  selectedBillboards: SelectedPostLink[];
  selectedShops: SelectedPostLink[];
  selectedShopProducts: SelectedPostLink[];
  selectedBooking: SelectedPostLink[];
  onPackagesChange: (links: SelectedPostLink[]) => void;
  onProjectsChange: (links: SelectedPostLink[]) => void;
  onBillboardsChange: (links: SelectedPostLink[]) => void;
  onShopsChange: (links: SelectedPostLink[]) => void;
  onShopProductsChange: (links: SelectedPostLink[]) => void;
  onBookingChange: (links: SelectedPostLink[]) => void;
}

function LinkListItem({
  title,
  imageSrc,
  fallbackIcon,
  isSelected,
  onToggle,
}: {
  title: string;
  imageSrc?: string | null;
  fallbackIcon: string;
  isSelected: boolean;
  onToggle: () => void;
}) {
  return (
    <li>
      <button
        type="button"
        onClick={onToggle}
        className={cn(
          "flex w-full items-center gap-2.5 rounded-lg px-2 py-2 text-right transition",
          isSelected
            ? "bg-pink-50 ring-1 ring-pink-300 dark:bg-pink-950/30 dark:ring-pink-700"
            : "hover:bg-neutral-100 dark:hover:bg-neutral-800"
        )}
      >
        <div className="relative flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-neutral-100 dark:bg-neutral-800">
          {imageSrc ? (
            <Image
              src={imageSrc}
              alt=""
              fill
              className="object-cover"
              unoptimized
            />
          ) : (
            <BoldIcon name={fallbackIcon} size={20} className="dark:invert" />
          )}
        </div>
        <span className="min-w-0 flex-1 truncate text-sm font-semibold">
          {title}
        </span>
        <span
          className={cn(
            "flex h-4 w-4 shrink-0 items-center justify-center rounded border-2",
            isSelected
              ? "border-pink-500 bg-pink-500 text-white"
              : "border-neutral-300 dark:border-neutral-600"
          )}
          aria-hidden
        >
          {isSelected ? (
            <BoldIcon name="tick-circle" size={10} tinted className="text-white" />
          ) : null}
        </span>
      </button>
    </li>
  );
}

function LinkSection({
  label,
  emptyText,
  loading,
  items,
  selectedIds,
  onToggle,
  getImage,
  fallbackIcon,
}: {
  label: string;
  emptyText: string;
  loading: boolean;
  items: Array<{ _id: string; title: string }>;
  selectedIds: string[];
  onToggle: (item: { _id: string; title: string }) => void;
  getImage?: (item: { _id: string; title: string }) => string | null;
  fallbackIcon: string;
}) {
  const { t } = useTranslation("common");
  if (loading) {
    return (
      <div className="space-y-2">
        <p className="text-xs font-semibold text-neutral-600 dark:text-neutral-300">
          {label}
        </p>
        <p className="text-xs text-neutral-400">{t("common.loading")}</p>
      </div>
    );
  }

  if (items.length === 0) {
    return (
      <div className="space-y-2">
        <p className="text-xs font-semibold text-neutral-600 dark:text-neutral-300">
          {label} ({t("posts.optional")})
        </p>
        <p className="rounded-xl border border-dashed border-neutral-200 px-3 py-2 text-xs text-neutral-400 dark:border-neutral-700">
          {emptyText}
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-2">
      <p className="text-xs font-semibold text-neutral-600 dark:text-neutral-300">
        {label} ({t("posts.optionalMulti")})
      </p>
      <ul className="max-h-36 space-y-1.5 overflow-y-auto rounded-xl border border-neutral-200 p-2 dark:border-neutral-700">
        {items.map((item) => (
          <LinkListItem
            key={item._id}
            title={item.title}
            imageSrc={getImage?.(item) ?? null}
            fallbackIcon={fallbackIcon}
            isSelected={selectedIds.includes(item._id)}
            onToggle={() => onToggle(item)}
          />
        ))}
      </ul>
    </div>
  );
}

function shopProductImage(listing: IShopProductListing) {
  const img = listing.images?.[listing.primaryImageIndex] || listing.images?.[0];
  return img ? IMAGE_BASE_URL + img : null;
}

function ShopLinkSection({
  shops,
  loading,
  selectedShopIds,
  selectedProductIds,
  onToggleShop,
  onToggleProduct,
}: {
  shops: MyShop[];
  loading: boolean;
  selectedShopIds: string[];
  selectedProductIds: string[];
  onToggleShop: (shop: MyShop) => void;
  onToggleProduct: (shopId: string, product: { _id: string; title: string }) => void;
}) {
  const { t } = useTranslation("common");
  const { request } = useAxios();
  const [expandedShopId, setExpandedShopId] = useState<string | null>(null);
  const [productsByShop, setProductsByShop] = useState<
    Record<string, IShopProductListing[]>
  >({});
  const [loadingProducts, setLoadingProducts] = useState(false);

  const toggleExpand = async (shopId: string) => {
    if (expandedShopId === shopId) {
      setExpandedShopId(null);
      return;
    }
    setExpandedShopId(shopId);
    if (productsByShop[shopId]) return;
    setLoadingProducts(true);
    try {
      const res = await request<{ docs: IShopProductListing[] }>(
        "GET",
        `/shop-products?shopId=${shopId}&limit=100`,
        null,
        { noToast: true }
      );
      setProductsByShop((prev) => ({ ...prev, [shopId]: res?.docs || [] }));
    } catch {
      setProductsByShop((prev) => ({ ...prev, [shopId]: [] }));
    } finally {
      setLoadingProducts(false);
    }
  };

  if (loading) {
    return (
      <div className="space-y-2">
        <p className="text-xs font-semibold text-neutral-600 dark:text-neutral-300">
          {t("posts.shop")}
        </p>
        <p className="text-xs text-neutral-400">{t("common.loading")}</p>
      </div>
    );
  }

  if (shops.length === 0) {
    return (
      <div className="space-y-2">
        <p className="text-xs font-semibold text-neutral-600 dark:text-neutral-300">
          {t("posts.shop")} ({t("posts.optional")})
        </p>
        <p className="rounded-xl border border-dashed border-neutral-200 px-3 py-2 text-xs text-neutral-400 dark:border-neutral-700">
          {t("posts.noShop")}
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-2">
      <p className="text-xs font-semibold text-neutral-600 dark:text-neutral-300">
        {t("posts.shop")} ({t("posts.optionalMulti")})
      </p>
      <ul className="max-h-64 space-y-1.5 overflow-y-auto rounded-xl border border-neutral-200 p-2 dark:border-neutral-700">
        {shops.map((shop) => {
          const isExpanded = expandedShopId === shop._id;
          const products = productsByShop[shop._id] || [];
          return (
            <li key={shop._id}>
              <div className="flex items-center gap-1">
                <div className="flex-1">
                  <LinkListItem
                    title={shop.name}
                    imageSrc={shop.logo ? IMAGE_BASE_URL + shop.logo : null}
                    fallbackIcon="shop"
                    isSelected={selectedShopIds.includes(shop._id)}
                    onToggle={() => onToggleShop(shop)}
                  />
                </div>
                <button
                  type="button"
                  onClick={() => void toggleExpand(shop._id)}
                  aria-label={t("posts.viewProducts")}
                  className="shrink-0 p-2"
                >
                  <BoldIcon
                    name="arrow-down-1"
                    size={14}
                    tinted
                    className={cn(
                      "text-neutral-400 transition-transform",
                      isExpanded && "rotate-180"
                    )}
                  />
                </button>
              </div>

              {isExpanded && (
                <ul className="mr-6 mt-1 space-y-1 border-r-2 border-neutral-100 pr-2 dark:border-neutral-800">
                  {loadingProducts && !productsByShop[shop._id] ? (
                    <li className="p-1 text-xs text-neutral-400">
                      {t("common.loading")}
                    </li>
                  ) : products.length === 0 ? (
                    <li className="p-1 text-xs text-neutral-400">
                      {t("shops.noProductsYet")}
                    </li>
                  ) : (
                    products.map((product) => (
                      <LinkListItem
                        key={product._id}
                        title={product.title}
                        imageSrc={shopProductImage(product)}
                        fallbackIcon="box"
                        isSelected={selectedProductIds.includes(product._id)}
                        onToggle={() =>
                          onToggleProduct(shop._id, {
                            _id: product._id,
                            title: product.title,
                          })
                        }
                      />
                    ))
                  )}
                </ul>
              )}
            </li>
          );
        })}
      </ul>
    </div>
  );
}

function courseImageSrc(course: Course) {
  if (!course.course_image) return null;
  return course.course_image.startsWith("http")
    ? course.course_image
    : `${IMAGE_BASE_URL}${course.course_image}`;
}

function billboardImageSrc(ad: IAdvertising) {
  const img = ad.images?.[0];
  if (!img) return null;
  return img.startsWith("http") ? img : `${IMAGE_BASE_URL}${img}`;
}

function toggleLink(
  current: SelectedPostLink[],
  kind: SelectedPostLink["kind"],
  item: { _id: string; title: string }
): SelectedPostLink[] {
  const exists = current.some((l) => l._id === item._id);
  if (exists) {
    return current.filter((l) => l._id !== item._id);
  }
  return [...current, { kind, _id: item._id, title: item.title }];
}

export default function PostLinkPicker({
  selectedPackages,
  selectedProjects,
  selectedBillboards,
  selectedShops,
  selectedShopProducts,
  selectedBooking,
  onPackagesChange,
  onProjectsChange,
  onBillboardsChange,
  onShopsChange,
  onShopProductsChange,
  onBookingChange,
}: PostLinkPickerProps) {
  const { t } = useTranslation("common");
  const { request } = useAxios();
  const user = useUser();

  const [courses, setCourses] = useState<Course[]>([]);
  const [projects, setProjects] = useState<Project[]>([]);
  const [billboards, setBillboards] = useState<IAdvertising[]>([]);
  const [shops, setShops] = useState<MyShop[]>([]);
  const [bookingConfig, setBookingConfig] = useState<{ name: string } | null>(null);
  const [loadingCourses, setLoadingCourses] = useState(true);
  const [loadingProjects, setLoadingProjects] = useState(true);
  const [loadingBillboards, setLoadingBillboards] = useState(true);
  const [loadingShops, setLoadingShops] = useState(true);
  const [loadingBooking, setLoadingBooking] = useState(true);

  const loadCourses = useCallback(async () => {
    setLoadingCourses(true);
    try {
      const response = await request<{
        success?: boolean;
        data?: { courses?: Course[] };
        courses?: Course[];
      }>("GET", "/academy/academy/get/course?page=1&limit=100", null, {
        noToast: true,
      });
      const list = response?.data?.courses ?? response?.courses ?? [];
      setCourses(Array.isArray(list) ? list : []);
    } catch {
      setCourses([]);
    } finally {
      setLoadingCourses(false);
    }
  }, [request]);

  const loadProjects = useCallback(async () => {
    if (!user?._id) {
      setProjects([]);
      setLoadingProjects(false);
      return;
    }
    setLoadingProjects(true);
    try {
      const endpoints = [
        `/projects/user-projects?user_id=${user._id}&page=1&limit=100&linkable=1`,
        `/projects/user-projects/web?user_id=${user._id}&page=1&limit=100&linkable=1`,
      ];
      let list: Project[] = [];
      for (const url of endpoints) {
        try {
          const response = await request<{
            data?: { projects?: Project[] };
            projects?: Project[];
          }>("GET", url, null, { noToast: true });
          list =
            response?.data?.projects ??
            response?.projects ??
            [];
          if (list.length) break;
        } catch {
          /* try next */
        }
      }
      setProjects(Array.isArray(list) ? list : []);
    } catch {
      setProjects([]);
    } finally {
      setLoadingProjects(false);
    }
  }, [request, user?._id]);

  const loadBillboards = useCallback(async () => {
    setLoadingBillboards(true);
    try {
      const response = await request<{
        advertisings?: IAdvertising[];
        data?: { advertisings?: IAdvertising[] };
      }>("GET", "/advertising/user-advertising?page=1&limit=100", null, {
        noToast: true,
      });
      const list =
        response?.advertisings ?? response?.data?.advertisings ?? [];
      setBillboards(Array.isArray(list) ? list : []);
    } catch {
      setBillboards([]);
    } finally {
      setLoadingBillboards(false);
    }
  }, [request]);

  const loadShops = useCallback(async () => {
    setLoadingShops(true);
    try {
      const response = await request<{ shops?: MyShop[] }>(
        "GET",
        "/shops/mine",
        null,
        { noToast: true }
      );
      setShops(Array.isArray(response?.shops) ? response.shops : []);
    } catch {
      setShops([]);
    } finally {
      setLoadingShops(false);
    }
  }, [request]);

  const loadBooking = useCallback(async () => {
    if (!user?._id) {
      setBookingConfig(null);
      setLoadingBooking(false);
      return;
    }
    setLoadingBooking(true);
    try {
      // یه کاربر حداکثر یه کانفیگ رزرو active داره — همون endpoint عمومی رو روی خودمون
      // صدا می‌زنیم، نیازی به endpoint جدا برای «کانفیگ خودم» نیست
      const response = await request<{ config?: { name: string } }>(
        "GET",
        `/bookings/public/${user._id}`,
        null,
        { noToast: true }
      );
      setBookingConfig(response?.config || null);
    } catch {
      setBookingConfig(null);
    } finally {
      setLoadingBooking(false);
    }
  }, [request, user?._id]);

  useEffect(() => {
    void loadCourses();
  }, [loadCourses]);

  useEffect(() => {
    void loadProjects();
  }, [loadProjects]);

  useEffect(() => {
    void loadBillboards();
  }, [loadBillboards]);

  useEffect(() => {
    void loadShops();
  }, [loadShops]);

  useEffect(() => {
    void loadBooking();
  }, [loadBooking]);

  const courseItems = courses
    .map((c) => ({
      _id: String(c._id || c.id || ""),
      title: c.cuorse_name || t("posts.defaultPackageTitle"),
      raw: c,
    }))
    .filter((c) => c._id);

  const projectItems = projects
    .map((p) => ({
      _id: String(p._id),
      title: p.title || t("posts.defaultProjectTitle"),
      raw: p,
    }))
    .filter((p) => p._id);

  const billboardItems = billboards
    .map((b) => ({
      _id: String(b._id),
      title: b.title || t("posts.defaultBillboardTitle"),
      raw: b,
    }))
    .filter((b) => b._id);

  // برخلاف بقیه، _id اینجا عمداً خودِ userId مالکه (نه شناسه‌ی کانفیگ رزرو) — چون صفحه‌ی
  // عمومی رزرو با userId مسیردهی می‌شه؛ کاربر همیشه فقط کانفیگ خودش رو لینک می‌کنه
  const bookingItems =
    bookingConfig && user?._id
      ? [{ _id: String(user._id), title: bookingConfig.name || t("posts.defaultBookingTitle") }]
      : [];

  return (
    <div className="space-y-4">
      <p className="text-xs text-neutral-500">{t("posts.linkHint")}</p>
      <LinkSection
        label={t("posts.trainingPackage")}
        emptyText={t("posts.noTrainingPackage")}
        loading={loadingCourses}
        items={courseItems}
        selectedIds={selectedPackages.map((p) => p._id)}
        onToggle={(item) =>
          onPackagesChange(toggleLink(selectedPackages, "pkg", item))
        }
        getImage={(item) => {
          const course = courseItems.find((c) => c._id === item._id)?.raw;
          return course ? courseImageSrc(course) : null;
        }}
        fallbackIcon="teacher"
      />
      <LinkSection
        label={t("posts.project")}
        emptyText={t("posts.noProject")}
        loading={loadingProjects}
        items={projectItems}
        selectedIds={selectedProjects.map((p) => p._id)}
        onToggle={(item) =>
          onProjectsChange(toggleLink(selectedProjects, "project", item))
        }
        fallbackIcon="briefcase"
      />
      <LinkSection
        label={t("posts.billboard")}
        emptyText={t("posts.noBillboard")}
        loading={loadingBillboards}
        items={billboardItems}
        selectedIds={selectedBillboards.map((p) => p._id)}
        onToggle={(item) =>
          onBillboardsChange(toggleLink(selectedBillboards, "billboard", item))
        }
        getImage={(item) => {
          const ad = billboardItems.find((b) => b._id === item._id)?.raw;
          return ad ? billboardImageSrc(ad) : null;
        }}
        fallbackIcon="flash-circle"
      />
      <ShopLinkSection
        shops={shops}
        loading={loadingShops}
        selectedShopIds={selectedShops.map((s) => s._id)}
        selectedProductIds={selectedShopProducts.map((s) => s._id)}
        onToggleShop={(shop) =>
          onShopsChange(toggleLink(selectedShops, "shop", { _id: shop._id, title: shop.name }))
        }
        onToggleProduct={(_shopId, product) =>
          onShopProductsChange(toggleLink(selectedShopProducts, "shopproduct", product))
        }
      />
      <LinkSection
        label={t("posts.booking")}
        emptyText={t("posts.noBooking")}
        loading={loadingBooking}
        items={bookingItems}
        selectedIds={selectedBooking.map((p) => p._id)}
        onToggle={(item) =>
          onBookingChange(toggleLink(selectedBooking, "booking", item))
        }
        fallbackIcon="calendar"
      />
    </div>
  );
}
