"use client";

// ============================================================================
// Placements Detail Page - All placements grouped by channel
// ============================================================================

import { useEffect, useState, useMemo, useCallback } from "react";
import { useParams, useRouter } from "next/navigation";
import Link from "next/link";
import {
  Loader2,
  Plus,
  ArrowLeft,
  ChevronDown,
  ChevronRight,
  Search,
  Filter,
  Eye,
  Users,
  ExternalLink,
  CircleDollarSign,
  TrendingUp,
  RefreshCw,
  Loader2 as LoaderIcon,
  BarChart3,
  ArrowUpDown,
  X,
} from "lucide-react";
import { DashboardHeader } from "@/components/layout/dashboard-header";
import { useWorkspace } from "@/components/providers/workspace-provider";
import { demoAwarePlacementsApi } from "@/lib/demo";
import { placementsApi } from "@/lib/api";
import { AddChannelDialog } from "@/components/dialog-add-channel";
import { CreatePlacementsDialog } from "@/components/dialog-create-placements";
import { FiltersModal, PlacementFilters } from "@/components/filters-modal";
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/components/ui/collapsible";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { cn } from "@/lib/utils";
import type {
  Project,
  Placement,
  PlacementWithStats,
  PlacementsGroupedByChannel,
  PlacementStatus,
} from "@/lib/types/api";

// ============================================================================
// Helpers
// ============================================================================

const formatNumber = (value: number | null | undefined): string => {
  if (value === null || value === undefined) return "—";
  return new Intl.NumberFormat("ru-RU").format(value);
};

const formatCurrency = (value: number | null | undefined): string => {
  if (value === null || value === undefined) return "—";
  return new Intl.NumberFormat("ru-RU", {
    style: "currency",
    currency: "RUB",
    minimumFractionDigits: 0,
    maximumFractionDigits: 0,
  }).format(value);
};

const formatCompact = (value: number | null | undefined): string => {
  if (value === null || value === undefined) return "—";
  if (value >= 1000000) return `${(value / 1000000).toFixed(1)}M`;
  if (value >= 1000) return `${(value / 1000).toFixed(1)}K`;
  return value.toString();
};

const formatDate = (dateStr: string | null): string => {
  if (!dateStr) return "—";
  const date = new Date(dateStr);
  return date.toLocaleDateString("ru-RU", {
    day: "2-digit",
    month: "short",
    year: "numeric",
  });
};

const PLACEMENT_STATUSES: PlacementStatus[] = [
  "Без статуса",
  "Написать",
  "Ждём ответа",
  "Согласование условий",
  "Оплатить",
  "Оплачено",
  "Отмена",
  "Не подходит цена",
  "Неактуально",
  "Не отвечает",
];

const getStatusColor = (status: PlacementStatus): string => {
  switch (status) {
    case "Оплачено":
      return "bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400 dark:border-emerald-800";
    case "Согласование условий":
    case "Ждём ответа":
      return "bg-amber-100 text-amber-700 border-amber-200 dark:bg-amber-900/30 dark:text-amber-400 dark:border-amber-800";
    case "Отмена":
    case "Не подходит цена":
    case "Неактуально":
    case "Не отвечает":
      return "bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-400 dark:border-red-800";
    case "Оплатить":
      return "bg-blue-100 text-blue-700 border-blue-200 dark:bg-blue-900/30 dark:text-blue-400 dark:border-blue-800";
    default:
      return "bg-muted text-muted-foreground border-border";
  }
};

// ============================================================================
// Components
// ============================================================================

interface ChannelGroupProps {
  channel: Placement["channel"];
  placements: PlacementWithStats[];
  channelNumber: number;
}

function ChannelGroup({ channel, placements, channelNumber }: ChannelGroupProps) {
  const [isOpen, setIsOpen] = useState(true);

  const totalCost = placements.reduce((sum, p) => sum + (p.details?.cost?.value || 0), 0);
  const totalSubscriptions = placements.reduce((sum, p) => sum + (p.placement_post?.subscriptions_count || 0), 0);
  const totalViews = placements.reduce((sum, p) => sum + (p.placement_post?.views_count || 0), 0);

  const avgCpf = totalSubscriptions > 0 ? totalCost / totalSubscriptions : null;
  const avgCpm = totalViews > 0 ? (totalCost / totalViews) * 1000 : null;

  if (placements.length === 0) return null;

  return (
    <div className="mb-3">
      <Collapsible open={isOpen} onOpenChange={setIsOpen}>
        <CollapsibleTrigger asChild>
          <div className="flex items-center gap-2 px-3 py-2 bg-muted/50 rounded-lg cursor-pointer hover:bg-muted transition-colors">
            <ChevronDown
              className={cn(
                "h-4 w-4 text-muted-foreground transition-transform",
                !isOpen && "-rotate-90"
              )}
            />
            <span className="text-xs font-mono text-muted-foreground bg-background px-1.5 py-0.5 rounded w-6 text-center">
              {channelNumber}
            </span>
            <Avatar className="h-8 w-8">
              <AvatarImage
                src={channel.username ? `https://t.me/i/userpic/160/${channel.username}.jpg` : undefined}
                alt={channel.title}
              />
              <AvatarFallback className="text-sm">
                {channel.title[0]}
              </AvatarFallback>
            </Avatar>
            <div className="flex flex-col">
              <span className="font-medium text-sm">{channel.title}</span>
              {channel.username && (
                <span className="text-xs text-muted-foreground">@{channel.username}</span>
              )}
            </div>
            {channel.username && (
              <div className="flex items-center gap-1 ml-2">
                <a
                  href={`https://telemetr.me/channel/${channel.username}`}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="flex items-center justify-center h-6 w-6 hover:opacity-75 transition-opacity"
                  onClick={(e) => e.stopPropagation()}
                >
                  <img src="/icons/telemetr.jpg" alt="TgStat" className="h-5 w-5 rounded" />
                </a>
                <a
                  href={`https://tgstat.ru/channel/@${channel.username}`}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="flex items-center justify-center h-6 w-6 hover:opacity-75 transition-opacity"
                  onClick={(e) => e.stopPropagation()}
                >
                  <img src="/icons/tgstat.jpg" alt="TgStat" className="h-5 w-5 rounded" />
                </a>
              </div>
            )}
            <Badge variant="outline" className="ml-auto text-xs">
              {placements.length}
            </Badge>
            <div className="flex items-center gap-3 text-xs text-muted-foreground ml-2">
              <span className="flex items-center gap-1">
                <Users className="h-3 w-3" />
                {formatCompact(channel.subscribers_count)}
              </span>
              <span className="flex items-center gap-1">
                <Eye className="h-3 w-3" />
                {formatCompact(totalViews)}
              </span>
            </div>
          </div>
        </CollapsibleTrigger>
        <CollapsibleContent>
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b">
                  <th className="text-left py-2 px-3 font-medium text-muted-foreground w-8"></th>
                  <th className="text-left py-2 px-3 font-medium text-muted-foreground w-16">№</th>
                  <th className="text-left py-2 px-3 font-medium text-muted-foreground w-28">Статус</th>
                  <th className="text-left py-2 px-3 font-medium text-muted-foreground w-28">Дата</th>
                  <th className="text-left py-2 px-3 font-medium text-muted-foreground w-24">Стоимость</th>
                  <th className="text-right py-2 px-3 font-medium text-muted-foreground w-20">Охват</th>
                  <th className="text-right py-2 px-3 font-medium text-muted-foreground w-20">Подписки</th>
                  <th className="text-right py-2 px-3 font-medium text-muted-foreground w-20">CPF</th>
                  <th className="text-right py-2 px-3 font-medium text-muted-foreground w-20">CPM</th>
                  <th className="text-left py-2 px-3 font-medium text-muted-foreground w-24">Формат</th>
                  <th className="text-left py-2 px-3 font-medium text-muted-foreground w-32">Комментарий</th>
                </tr>
              </thead>
              <tbody>
                {placements.map((placement, idx) => {
                  const cpf = placement.placement_post?.subscriptions_count
                    ? (placement.details?.cost?.value || 0) / placement.placement_post.subscriptions_count
                    : null;
                  const cpm = placement.placement_post?.views_count
                    ? ((placement.details?.cost?.value || 0) / placement.placement_post.views_count) * 1000
                    : null;

                  return (
                    <tr key={placement.id} className="border-b last:border-0 hover:bg-muted/30">
                      <td className="py-2 px-3"></td>
                      <td className="py-2 px-3">
                        <span className="text-xs font-mono text-muted-foreground bg-muted px-1.5 py-0.5 rounded">
                          {channelNumber}.{idx + 1}
                        </span>
                      </td>
                      <td className="py-2 px-3">
                        <span className={cn(
                          "inline-flex items-center px-2 py-0.5 rounded text-xs font-medium border",
                          getStatusColor(placement.status)
                        )}>
                          {placement.status}
                        </span>
                      </td>
                      <td className="py-2 px-3 text-muted-foreground">
                        {formatDate(placement.details?.placement_at || null)}
                      </td>
                      <td className="py-2 px-3 font-medium">
                        {formatCurrency(placement.details?.cost?.value || null)}
                      </td>
                      <td className="py-2 px-3 text-right text-muted-foreground">
                        {formatCompact(placement.placement_post?.views_count || null)}
                      </td>
                      <td className="py-2 px-3 text-right text-muted-foreground">
                        {formatNumber(placement.placement_post?.subscriptions_count || null)}
                      </td>
                      <td className="py-2 px-3 text-right font-medium">
                        {formatCurrency(cpf)}
                      </td>
                      <td className="py-2 px-3 text-right font-medium">
                        {formatCurrency(cpm)}
                      </td>
                      <td className="py-2 px-3 text-muted-foreground">
                        {placement.details?.format || "—"}
                      </td>
                      <td className="py-2 px-3 text-muted-foreground max-w-[150px] truncate">
                        {placement.comment || "—"}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </CollapsibleContent>
      </Collapsible>
    </div>
  );
}

// ============================================================================
// Main Component
// ============================================================================

export default function PurchasePlanDetailPage() {
  const params = useParams();
  const router = useRouter();
  const workspaceId = params?.workspaceId as string;
  const projectId = params?.projectId as string;
  const { projects, hasPermission } = useWorkspace();

  const [placements, setPlacements] = useState<Placement[]>([]);
  const [loading, setLoading] = useState(true);
  const [project, setProject] = useState<Project | null>(null);

  const [searchQuery, setSearchQuery] = useState("");
  const [statusFilter, setStatusFilter] = useState("all");
  const [expandedAll, setExpandedAll] = useState(true);
  const [filtersOpen, setFiltersOpen] = useState(false);
  const [filters, setFilters] = useState<PlacementFilters>({
    channelFilters: {
      name: { value: "", condition: "contains" },
      username: { value: "", condition: "contains" },
      subscribersMin: null,
      subscribersMax: null,
    },
    placementFilters: {
      statuses: [],
      costMin: null,
      costMax: null,
      dateFrom: null,
      dateTo: null,
      hasPlacement: null,
    },
    sort: null,
  });

  const { isDemoMode } = useWorkspace();

  useEffect(() => {
    const proj = projects.find((p) => p.id === projectId);
    if (proj) {
      setProject(proj);
    }
  }, [projects, projectId]);

  useEffect(() => {
    loadPlacements();
  }, [workspaceId, projectId]);

  const loadPlacements = async () => {
    try {
      setLoading(true);
      const api = isDemoMode ? demoAwarePlacementsApi : placementsApi;
      const data = await api.getByProject(workspaceId, projectId);
      setPlacements(data);
    } catch (err) {
      console.error("Failed to load placements:", err);
    } finally {
      setLoading(false);
    }
  };

  const groupedPlacements = useMemo(() => {
    const groups: Record<string, { channel: Placement["channel"]; placements: PlacementWithStats[] }> = {};

    placements.forEach((placement) => {
      const channelId = placement.channel.id;
      if (!groups[channelId]) {
        groups[channelId] = {
          channel: placement.channel,
          placements: [],
        };
      }

      const cpf = placement.placement_post?.subscriptions_count
        ? (placement.details?.cost?.value || 0) / placement.placement_post.subscriptions_count
        : null;
      const cpm = placement.placement_post?.views_count
        ? ((placement.details?.cost?.value || 0) / placement.placement_post.views_count) * 1000
        : null;

      groups[channelId].placements.push({
        ...placement,
        cpf,
        cpm,
      });
    });

    return Object.entries(groups).map(([_, group]) => ({
      channel: group.channel,
      placements: group.placements,
    }));
  }, [placements]);

  const summary = useMemo(() => {
    const totalCost = placements.reduce((sum, p) => sum + (p.details?.cost?.value || 0), 0);
    const totalSubscriptions = placements.reduce((sum, p) => sum + (p.placement_post?.subscriptions_count || 0), 0);
    const totalViews = placements.reduce((sum, p) => sum + (p.placement_post?.views_count || 0), 0);

    return {
      totalPlacements: placements.length,
      totalChannels: groupedPlacements.length,
      totalCost,
      totalSubscriptions,
      totalViews,
      avgCpf: totalSubscriptions > 0 ? totalCost / totalSubscriptions : null,
      avgCpm: totalViews > 0 ? (totalCost / totalViews) * 1000 : null,
    };
  }, [placements, groupedPlacements]);

   const filteredGroups = useMemo(() => {
    let filtered = groupedPlacements.filter((group) => {
      // Channel filters
      const nameFilter = filters.channelFilters.name;
      const channelNameMatch = !nameFilter.value ||
        (nameFilter.condition === "contains"
          ? group.channel.title.toLowerCase().includes(nameFilter.value.toLowerCase())
          : nameFilter.condition === "not_contains"
          ? !group.channel.title.toLowerCase().includes(nameFilter.value.toLowerCase())
          : group.channel.title.toLowerCase() === nameFilter.value.toLowerCase());

      const usernameFilter = filters.channelFilters.username;
      const channelUsernameMatch = !usernameFilter.value ||
        (usernameFilter.condition === "contains"
          ? group.channel.username?.toLowerCase().includes(usernameFilter.value.toLowerCase())
          : usernameFilter.condition === "not_contains"
          ? !group.channel.username?.toLowerCase().includes(usernameFilter.value.toLowerCase())
          : group.channel.username?.toLowerCase() === usernameFilter.value.toLowerCase());

      const subscribersMinMatch = filters.channelFilters.subscribersMin === null ||
        (group.channel.subscribers_count || 0) >= filters.channelFilters.subscribersMin;
      const subscribersMaxMatch = filters.channelFilters.subscribersMax === null ||
        (group.channel.subscribers_count || 0) <= filters.channelFilters.subscribersMax;

      // Placement filters
      const placementsWithStatus = filters.placementFilters.statuses.length === 0 ||
        group.placements.some((p) => filters.placementFilters.statuses.includes(p.status));

      const costMinMatch = filters.placementFilters.costMin === null ||
        group.placements.some((p) => (p.details?.cost?.value || 0) >= filters.placementFilters.costMin!);
      const costMaxMatch = filters.placementFilters.costMax === null ||
        group.placements.some((p) => (p.details?.cost?.value || 0) <= filters.placementFilters.costMax!);

      let dateMatch = true;
      if (filters.placementFilters.dateFrom || filters.placementFilters.dateTo) {
        dateMatch = group.placements.some((p) => {
          if (!p.details?.placement_at) return false;
          const placementDate = new Date(p.details.placement_at);
          const fromMatch = !filters.placementFilters.dateFrom ||
            placementDate >= new Date(filters.placementFilters.dateFrom);
          const toMatch = !filters.placementFilters.dateTo ||
            placementDate <= new Date(filters.placementFilters.dateTo);
          return fromMatch && toMatch;
        });
      }

      return channelNameMatch && channelUsernameMatch && subscribersMinMatch &&
        subscribersMaxMatch && placementsWithStatus && costMinMatch && costMaxMatch && dateMatch;
    });

    // Apply sorting
    if (filters.sort) {
      filtered = [...filtered].sort((a, b) => {
        let aValue: number | string = 0;
        let bValue: number | string = 0;

        switch (filters.sort!.field) {
          case "title":
            aValue = a.channel.title.toLowerCase();
            bValue = b.channel.title.toLowerCase();
            break;
          case "subscribers":
            aValue = a.channel.subscribers_count || 0;
            bValue = b.channel.subscribers_count || 0;
            break;
          case "cost":
            aValue = Math.max(...a.placements.map((p) => p.details?.cost?.value || 0));
            bValue = Math.max(...b.placements.map((p) => p.details?.cost?.value || 0));
            break;
          case "date":
            aValue = Math.max(
              ...a.placements.map((p) => p.details?.placement_at ? new Date(p.details.placement_at).getTime() : 0)
            );
            bValue = Math.max(
              ...b.placements.map((p) => p.details?.placement_at ? new Date(p.details.placement_at).getTime() : 0)
            );
            break;
          case "cpm":
            aValue = a.placements[0]?.cpm || 0;
            bValue = b.placements[0]?.cpm || 0;
            break;
          case "cpf":
            aValue = a.placements[0]?.cpf || 0;
            bValue = b.placements[0]?.cpf || 0;
            break;
        }

        if (typeof aValue === "string") {
          return filters.sort!.direction === "asc"
            ? aValue.localeCompare(bValue as string)
            : (bValue as string).localeCompare(aValue);
        }
        return filters.sort!.direction === "asc"
          ? (aValue as number) - (bValue as number)
          : (bValue as number) - (aValue as number);
      });
    }

    return filtered;
  }, [groupedPlacements, filters]);

  const canWrite = hasPermission("placements_write");

  const hasActiveFilters = filters.channelFilters.name ||
    filters.channelFilters.username ||
    filters.channelFilters.subscribersMin !== null ||
    filters.channelFilters.subscribersMax !== null ||
    filters.placementFilters.statuses.length > 0 ||
    filters.placementFilters.costMin !== null ||
    filters.placementFilters.costMax !== null ||
    filters.placementFilters.dateFrom ||
    filters.placementFilters.dateTo ||
    filters.sort;

  if (loading) {
    return (
      <>
        <DashboardHeader breadcrumbs={[{ label: "Загрузка..." }]} />
        <div className="flex items-center justify-center py-12">
          <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
        </div>
      </>
    );
  }

  return (
    <>
      <DashboardHeader
        breadcrumbs={[
          { label: "Главная", href: `/dashboard/${workspaceId}` },
          { label: "Размещения", href: `/dashboard/${workspaceId}/purchase-plans` },
          { label: project?.title || "Проект" },
        ]}
      />

      <div className="flex flex-1 flex-col gap-4 p-4 pt-0 mt-4">
        {/* Header */}
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-4">
            <Button
              variant="ghost"
              size="icon"
              onClick={() => router.push(`/dashboard/${workspaceId}/purchase-plans`)}
            >
              <ArrowLeft className="h-4 w-4" />
            </Button>
            <div>
              <h1 className="text-2xl font-bold tracking-tight">
                План закупов проекта «{project?.title || "Проект"}»
              </h1>
              <p className="text-muted-foreground">
                Список каналов, в которых планируем размещения для проекта
              </p>
            </div>
          </div>
          <div className="flex items-center gap-2">
            <AddChannelDialog
              workspaceId={workspaceId}
              projectId={projectId}
              existingPlacements={placements}
              onSuccess={loadPlacements}
            >
              <Button variant="outline" disabled={isDemoMode}>
                <Plus className="h-4 w-4 mr-2" />
                Добавить канал
              </Button>
            </AddChannelDialog>
            <CreatePlacementsDialog
              workspaceId={workspaceId}
              projectId={projectId}
              existingPlacements={placements}
              onSuccess={loadPlacements}
            >
              <Button disabled={isDemoMode}>
                <Plus className="h-4 w-4 mr-2" />
                Создать размещения
              </Button>
            </CreatePlacementsDialog>
          </div>
        </div>

        {/* Filters */}
        <div className="flex items-center gap-3">
          <div className="relative flex-1 max-w-sm">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder="Поиск канала..."
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="pl-9"
            />
          </div>
          <Button
            variant={hasActiveFilters ? "default" : "outline"}
            size="sm"
            onClick={() => setFiltersOpen(true)}
          >
            <Filter className="h-4 w-4 mr-1" />
            Фильтры
            {hasActiveFilters && (
              <span className="ml-1 px-1.5 py-0.5 text-xs bg-primary-foreground/20 rounded">
                ✓
              </span>
            )}
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={() => setExpandedAll(!expandedAll)}
          >
            {expandedAll ? "Свернуть все" : "Развернуть все"}
          </Button>
        </div>

        {/* Placements List */}
        {filteredGroups.length === 0 ? (
          <Card>
            <CardContent className="flex flex-col items-center justify-center py-12">
              <TrendingUp className="h-12 w-12 text-muted-foreground mb-4" />
              <h3 className="text-lg font-semibold mb-2">Нет размещений</h3>
              <p className="text-muted-foreground text-center">
                {placements.length === 0
                  ? "Добавьте первое размещение для этого проекта"
                  : "Попробуйте изменить параметры поиска"}
              </p>
            </CardContent>
          </Card>
        ) : (
          <div className="space-y-1">
            {filteredGroups.map((group, idx) => (
              <ChannelGroup
                key={group.channel.id}
                channel={group.channel}
                placements={group.placements}
                channelNumber={idx + 1}
              />
            ))}
          </div>
        )}
      </div>

      <FiltersModal
        open={filtersOpen}
        onOpenChange={setFiltersOpen}
        onApply={setFilters}
        existingPlacements={placements}
        initialFilters={filters}
      />
    </>
  );
}
