import { useState, useEffect } from "react";
import { motion } from "framer-motion";
import type { Variants } from "framer-motion";
import { UploadCloud, Search, File, CheckCircle, Share2 } from "lucide-react";
import { useAuthStore } from "../hooks/use-auth";
import { axiosInstance } from "../services/axios";
import {
  getAssets,
  getOrganizations,
  deleteAsset,
  requestDownload,
  approveDownloadRequest,
  rejectDownloadRequest,
  downloadAssetFile,
} from "../services/assets-api";
import { useToast } from "../hooks/use-toast";

// Subcomponents
import { AssetCard } from "../features/assets/components/AssetCard";
import { UploadAssetModal } from "../features/assets/components/UploadAssetModal";
import { EditAssetModal } from "../features/assets/components/EditAssetModal";
import { ShareAssetModal } from "../features/assets/components/ShareAssetModal";
import { AssetDetailsModal } from "../features/assets/components/AssetDetailsModal";
import { AssetViewerModal } from "../features/assets/components/AssetViewerModal";
import { DownloadRequestsModal } from "../features/assets/components/DownloadRequestsModal";
import { PageHeader } from "../components/ui/PageHeader";
import Button from "../components/ui/Button";
import { PageLayout } from "../components/layout/PageLayout";

// Type Definitions
import type { Asset, Organization } from "../types/assets";

const containerVariants: Variants = {
  hidden: { opacity: 0 },
  show: { opacity: 1, transition: { staggerChildren: 0.05 } },
};

const itemVariants: Variants = {
  hidden: { opacity: 0, y: 15, scale: 0.98 },
  show: {
    opacity: 1,
    y: 0,
    scale: 1,
    transition: { type: "spring", stiffness: 350, damping: 25 },
  },
};

export const AssetsPage = () => {
  const { success, error } = useToast();
  const user = useAuthStore((state) => state.user);
  const [assets, setAssets] = useState<Asset[]>([]);
  const [organizations, setOrganizations] = useState<Organization[]>([]);
  const [loading, setLoading] = useState(true);

  // Search & Filter
  const [searchQuery, setSearchQuery] = useState("");
  const [selectedCategory, setSelectedCategory] = useState<string>("ALL");

  // Modal Control States
  const [isUploadOpen, setIsUploadOpen] = useState(false);
  const [isEditOpen, setIsEditOpen] = useState(false);
  const [isShareOpen, setIsShareOpen] = useState(false);
  const [isDetailsOpen, setIsDetailsOpen] = useState(false);
  const [isViewerOpen, setIsViewerOpen] = useState(false);
  const [isRequestsOpen, setIsRequestsOpen] = useState(false);

  const [activeAsset, setActiveAsset] = useState<Asset | null>(null);
  const [activeMenuId, setActiveMenuId] = useState<string | null>(null);
  const [selectedAssetIds, setSelectedAssetIds] = useState<string[]>([]);

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    setLoading(true);
    try {
      const assetsData = await getAssets();
      setAssets(assetsData);
      setSelectedAssetIds([]);

      if (user?.role === "ADMIN") {
        const orgsData = await getOrganizations();
        setOrganizations(orgsData);
      }
    } catch (err) {
      console.error("Failed to fetch assets data", err);
    } finally {
      setLoading(false);
    }
  };

  const openEditModal = (asset: Asset) => {
    setActiveAsset(asset);
    setIsEditOpen(true);
  };

  const openShareModal = (asset: Asset) => {
    setSelectedAssetIds([]);
    setActiveAsset(asset);
    setIsShareOpen(true);
  };

  const handleToggleSelectAsset = (assetId: string) => {
    setSelectedAssetIds((prev) =>
      prev.includes(assetId)
        ? prev.filter((id) => id !== assetId)
        : [...prev, assetId]
    );
  };

  const openViewerModal = (asset: Asset) => {
    setActiveAsset(asset);
    setIsViewerOpen(true);
  };

  const openDetailsModal = (asset: Asset) => {
    setActiveAsset(asset);
    setIsDetailsOpen(true);
  };

  const handleDeleteAsset = async (id: string) => {
    const asset = assets.find(a => a.id === id);
    const title = asset ? asset.title : "this asset";
    if (
      !window.confirm(`Are you sure you want to permanently delete "${title}"?`)
    )
      return;
    try {
      await deleteAsset(id);
      success("Asset deleted successfully", `"${title}" has been permanently removed.`);
      await fetchData();
    } catch (err: any) {
      console.error("Failed to delete asset", err);
      error("Failed to delete asset", err.response?.data?.error || "Something went wrong.");
    }
  };

  const handleRequestDownload = async (asset: Asset) => {
    try {
      await requestDownload(asset.id);
      success("Download request submitted", "An administrator has been notified of your request.");
      await fetchData();
    } catch (err: any) {
      console.error("Failed to request download access", err);
      error("Failed to submit request", err.response?.data?.error || "Something went wrong.");
    }
  };

  const handleApproveRequest = async (assetId: string, requestId: string) => {
    try {
      await approveDownloadRequest(assetId, requestId);
      success("Download request approved", "The partner can now download this asset.");
      await fetchData();
    } catch (err: any) {
      console.error("Failed to approve request", err);
      error("Failed to approve request", err.response?.data?.error || "Something went wrong.");
    }
  };

  const handleRejectRequest = async (assetId: string, requestId: string) => {
    try {
      await rejectDownloadRequest(assetId, requestId);
      success("Download request rejected", "The access request was denied.");
      await fetchData();
    } catch (err: any) {
      console.error("Failed to reject request", err);
      error("Failed to reject request", err.response?.data?.error || "Something went wrong.");
    }
  };

  const handleDownload = async (asset: Asset) => {
    success("Download started", `Downloading "${asset.title}"...`);
    try {
      await downloadAssetFile(asset.id);

      const downloadUrl = asset.url.startsWith("http")
        ? asset.url
        : `${axiosInstance.defaults.baseURL?.replace("/api/v1", "")}${asset.url}`;

      const a = document.createElement("a");
      a.href = downloadUrl;
      a.download = asset.title;
      a.target = "_blank";
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);

      setAssets((prev) =>
        prev.map((item) =>
          item.id === asset.id
            ? { ...item, downloadsCount: item.downloadsCount + 1 }
            : item,
        ),
      );
    } catch (err: any) {
      console.error("Failed to process download", err);
      error("Download failed", err.response?.data?.error || "Could not retrieve asset file.");
    }
  };

  const CATEGORIES = [
    "ALL",
    "Marketing",
    "Presentations",
    "Branding",
    "Resources",
    "Technical",
  ];

  const filteredAssets = assets.filter((asset) => {
    const query = searchQuery.toLowerCase().trim();

    const matchesSearch =
      !query ||
      asset.title.toLowerCase().includes(query) ||
      (asset.description && asset.description.toLowerCase().includes(query)) ||
      (asset.categoryId && asset.categoryId.toLowerCase().includes(query)) ||
      (asset.subcategory && asset.subcategory.toLowerCase().includes(query)) ||
      (asset.githubUrl && asset.githubUrl.toLowerCase().includes(query)) ||
      asset.type.toLowerCase().includes(query) ||
      asset.tags.some((tag) => tag.toLowerCase().includes(query));

    const matchesCategory =
      selectedCategory === "ALL" || asset.categoryId === selectedCategory;

    return matchesSearch && matchesCategory;
  });

  const pendingRequestsCount = assets.reduce((acc, asset) => {
    return (
      acc +
      (asset.downloadRequests?.filter((r) => r.status === "PENDING").length ||
        0)
    );
  }, 0);

  // Header component
  const headerNode = (
    <PageHeader
      title="Asset Library"
      subtitle="Securely manage, distribute, and track marketing collateral and partner resources."
      badge={
        <div className="inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full bg-ink-100 border border-ink-200 text-[10px] font-bold text-ink-900 tracking-wider uppercase shrink-0">
          <CheckCircle className="w-3.5 h-3.5 text-ink-950" />
          <span>Global CDN Active</span>
        </div>
      }
    />
  );

  // Toolbar component
  const toolbarNode = (
    <div className="flex flex-col md:flex-row gap-4 items-center justify-between p-3.5 bg-ink-0 border border-ink-200 rounded-xl shadow-sm">
      <div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-2 flex-1 w-full max-w-2xl">
        <div className="relative flex-1 group">
          <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
            <Search className="w-4 h-4 text-ink-400 group-focus-within:text-ink-900 transition-colors" />
          </div>
          <input
            type="text"
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="w-full bg-ink-50 border border-ink-200 rounded-lg py-1.5 pl-9 pr-4 text-xs font-semibold text-ink-900 placeholder-ink-400 outline-none transition-all focus:border-ink-900/50 focus:ring-2 ring-ink-900/10 hover:border-ink-300 font-sans"
            placeholder="Search by title, desc, tag, category..."
          />
        </div>

        <div className="flex gap-1.5 overflow-x-auto pb-1 sm:pb-0 scrollbar-none">
          {CATEGORIES.map((cat) => (
            <button
              key={cat}
              onClick={() => setSelectedCategory(cat)}
              className={`px-2.5 py-1.5 rounded-lg border text-[10px] uppercase tracking-wider font-bold transition-all whitespace-nowrap shadow-sm cursor-pointer ${
                selectedCategory === cat
                  ? "bg-ink-900 text-ink-0 border-ink-900"
                  : "bg-ink-50 text-ink-700 border-ink-200 hover:bg-ink-100"
              }`}
            >
              {cat}
            </button>
          ))}
        </div>
      </div>

      <div className="flex items-center gap-2 shrink-0 w-full md:w-auto justify-end">
        {user?.role === "ADMIN" && pendingRequestsCount > 0 && (
          <Button
            onClick={() => setIsRequestsOpen(true)}
            variant="secondary"
            size="sm"
            icon={
              <span className="w-4 h-4 rounded-full bg-ink-900 text-ink-0 text-[10px] flex items-center justify-center font-extrabold mr-0.5">
                {pendingRequestsCount}
              </span>
            }
          >
            Download Requests
          </Button>
        )}

        {user?.role === "ADMIN" && selectedAssetIds.length > 0 && (
          <Button
            onClick={() => {
              setActiveAsset(null);
              setIsShareOpen(true);
            }}
            variant="secondary"
            size="sm"
            icon={<Share2 className="w-3.5 h-3.5" />}
          >
            Share Selected ({selectedAssetIds.length})
          </Button>
        )}

        {user?.role === "ADMIN" && (
          <Button
            onClick={() => setIsUploadOpen(true)}
            variant="primary"
            size="sm"
            icon={<UploadCloud className="w-3.5 h-3.5" />}
          >
            Create / Upload Asset
          </Button>
        )}
      </div>
    </div>
  );

  return (
    <PageLayout header={headerNode} toolbar={toolbarNode}>
      <div className="p-5 flex-1 min-h-0 overflow-y-auto">
        {loading ? (
          <div className="py-20 flex justify-center items-center">
            <div className="w-8 h-8 border-4 border-ink-900/30 border-t-ink-900 rounded-full animate-spin" />
          </div>
        ) : filteredAssets.length === 0 ? (
          <div className="py-12 text-center bg-ink-0 border border-ink-200 rounded-xl">
            <File className="w-12 h-12 text-ink-300 mx-auto mb-4" />
            <h3 className="text-lg font-bold text-ink-900">No assets found</h3>
            <p className="text-ink-500 text-sm mt-1">
              There are no assets matching your criteria.
            </p>
          </div>
        ) : (
          <motion.div
            variants={containerVariants}
            initial="hidden"
            animate="show"
            className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4"
          >
            {filteredAssets.map((asset) => (
              <motion.div key={asset.id} variants={itemVariants}>
                <AssetCard
                  asset={asset}
                  user={user}
                  activeMenuId={activeMenuId}
                  setActiveMenuId={setActiveMenuId}
                  onViewDetails={openDetailsModal}
                  onEdit={openEditModal}
                  onShare={openShareModal}
                  onDelete={handleDeleteAsset}
                  onOpenViewer={openViewerModal}
                  onDownload={handleDownload}
                  onRequestDownload={handleRequestDownload}
                  isSelected={selectedAssetIds.includes(asset.id)}
                  onToggleSelect={handleToggleSelectAsset}
                />
              </motion.div>
            ))}
          </motion.div>
        )}
      </div>

      {/* Modals Container */}
      <UploadAssetModal
        isOpen={isUploadOpen}
        onClose={() => setIsUploadOpen(false)}
        onSuccess={fetchData}
      />

      <EditAssetModal
        isOpen={isEditOpen}
        onClose={() => {
          setIsEditOpen(false);
          setActiveAsset(null);
        }}
        asset={activeAsset}
        onSuccess={fetchData}
      />

      <ShareAssetModal
        isOpen={isShareOpen}
        onClose={() => {
          setIsShareOpen(false);
          setActiveAsset(null);
          setSelectedAssetIds([]);
        }}
        asset={activeAsset}
        assetIds={selectedAssetIds}
        organizations={organizations}
        onSuccess={fetchData}
      />

      <AssetDetailsModal
        isOpen={isDetailsOpen}
        onClose={() => {
          setIsDetailsOpen(false);
          setActiveAsset(null);
        }}
        asset={activeAsset}
        userRole={user?.role}
      />

      <AssetViewerModal
        isOpen={isViewerOpen}
        onClose={() => {
          setIsViewerOpen(false);
          setActiveAsset(null);
        }}
        asset={activeAsset}
        user={user}
        onDownload={handleDownload}
      />

      <DownloadRequestsModal
        isOpen={isRequestsOpen}
        onClose={() => setIsRequestsOpen(false)}
        assets={assets}
        onApprove={handleApproveRequest}
        onReject={handleRejectRequest}
      />
    </PageLayout>
  );
};

export default AssetsPage;
