"use client";

// ============================================================================
// Placements List Page - Enhanced with Totals Row and Export
// ============================================================================

import { useEffect, useState, useMemo, useCallback } from "react";
import { useParams } from "next/navigation";
import Link from "next/link";
import {
  Loader2,
  Search,
  Plus,
  ShoppingCart,
  MoreHorizontal,
  Eye,
  ExternalLink,
  ArrowUpDown,
  ArrowUp,
  ArrowDown,
  Download,
  FileSpreadsheet,
  FileText,
  Info,
} from "lucide-react";
import { DashboardHeader } from "@/components/layout/dashboard-header";
import { useWorkspace } from "@/components/providers/workspace-provider";
import { demoAwarePlacementsApi } from "@/lib/demo";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent } from "@/components/ui/card";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
  TableFooter,
} from "@/components/ui/table";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
  DropdownMenuSeparator,
  DropdownMenuLabel,
} from "@/components/ui/dropdown-menu";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip";
import { Checkbox } from "@/components/ui/checkbox";
import { Label } from "@/components/ui/label";
import type { Placement } from "@/lib/types/api";

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

const formatDate = (dateString: string) => {
  return new Date(dateString).toLocaleDateString("ru-RU", {
    day: "numeric",
    month: "short",
    year: "numeric",
  });
};

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

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

const calculateCPS = (cost: number | null, subscriptions: number) => {
  if (!cost || subscriptions === 0) return null;
  return cost / subscriptions;
};

const calculateCPM = (cost: number | null | undefined, views: number | null | undefined) => {
  if (!cost || !views || views === 0) return null;
  return (cost / views) * 1000;
};

// ============================================================================
// Sort Types
// ============================================================================

type SortField = "date" | "cost" | "subscriptions" | "views" | "cps" | "cpm" | "status";
type SortOrder = "asc" | "desc" | null;

// ============================================================================
// Aggregation Functions
// ============================================================================

type AggFunc = "sum" | "avg" | "median" | "max" | "min";

const aggregationFunctions: Record<AggFunc, { label: string; fn: (values: number[]) => number | null }> = {
  sum: {
    label: "Сумма",
    fn: (values) => (values.length > 0 ? values.reduce((a, b) => a + b, 0) : null),
  },
  avg: {
    label: "Среднее",
    fn: (values) => (values.length > 0 ? values.reduce((a, b) => a + b, 0) / values.length : null),
  },
  median: {
    label: "Медиана",
    fn: (values) => {
      if (values.length === 0) return null;
      const sorted = [...values].sort((a, b) => a - b);
      const mid = Math.floor(sorted.length / 2);
      return sorted.length % 2 !== 0 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
    },
  },
  max: {
    label: "Макс.",
    fn: (values) => (values.length > 0 ? Math.max(...values) : null),
  },
  min: {
    label: "Мин.",
    fn: (values) => (values.length > 0 ? Math.min(...values) : null),
  },
};

// ============================================================================
// Export Functions
// ============================================================================

const exportToCSV = (placements: Placement[], filename: string) => {
  const headers = [
    "Канал",
    "Username",
    "Креатив",
    "Дата",
    "Стоимость",
    "Подписки",
    "Просмотры",
    "CPS",
    "CPM",
    "Статус",
    "Ссылка на пост",
    "Пригласительная ссылка",
  ];

  const rows = placements.map((p) => [
    p.placement_channel_title,
    "",
    p.creative_name,
    new Date(p.placement_date).toISOString().split("T")[0],
    p.cost?.toString() || "",
    p.subscriptions_count.toString(),
    p.views_count?.toString() || "",
    calculateCPS(p.cost, p.subscriptions_count)?.toFixed(2) || "",
    calculateCPM(p.cost, p.views_count)?.toFixed(2) || "",
    p.status,
    p.ad_post_url || "",
    p.invite_link,
  ]);

  const csv = [headers.join(";"), ...rows.map((r) => r.join(";"))].join("\n");
  const blob = new Blob(["\uFEFF" + csv], { type: "text/csv;charset=utf-8;" });
  downloadBlob(blob, `${filename}.csv`);
};

const exportToExcel = (placements: Placement[], filename: string) => {
  // Simple XLSX-like TSV format (opens in Excel)
  const headers = [
    "Канал",
    "Username",
    "Креатив",
    "Дата",
    "Стоимость",
    "Подписки",
    "Просмотры",
    "CPS",
    "CPM",
    "Статус",
  ];

  const rows = placements.map((p) => [
    p.placement_channel_title,
    "",
    p.creative_name,
    new Date(p.placement_date).toISOString().split("T")[0],
    p.cost?.toString() || "",
    p.subscriptions_count.toString(),
    p.views_count?.toString() || "",
    calculateCPS(p.cost, p.subscriptions_count)?.toFixed(2) || "",
    calculateCPM(p.cost, p.views_count)?.toFixed(2) || "",
    p.status,
  ]);

  const tsv = [headers.join("\t"), ...rows.map((r) => r.join("\t"))].join("\n");
  const blob = new Blob(["\uFEFF" + tsv], {
    type: "application/vnd.ms-excel;charset=utf-8;",
  });
  downloadBlob(blob, `${filename}.xls`);
};

const exportToTxt = (placements: Placement[], filename: string) => {
  const lines = placements.map((p) => {
    const cps = calculateCPS(p.cost, p.subscriptions_count);
    const cpm = calculateCPM(p.cost, p.views_count);
    return [
      `Канал: ${p.placement_channel_title}`,
      `Креатив: ${p.creative_name}`,
      `Дата: ${formatDate(p.placement_date)}`,
      `Стоимость: ${formatCurrency(p.cost)}`,
      `Подписки: ${p.subscriptions_count}`,
      `Просмотры: ${p.views_count || "—"}`,
      `CPS: ${cps ? formatCurrency(cps) : "—"}`,
      `CPM: ${cpm ? formatCurrency(cpm) : "—"}`,
      `Ссылка: ${p.invite_link}`,
      "---",
    ].join("\n");
  });

  const text = lines.join("\n");
  const blob = new Blob([text], { type: "text/plain;charset=utf-8;" });
  downloadBlob(blob, `${filename}.txt`);
};

const downloadBlob = (blob: Blob, filename: string) => {
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
};

// ============================================================================
// Component
// ============================================================================

export default function PlacementsPage() {
  const params = useParams();
  const workspaceId = params?.workspaceId as string;
  const { selectedProjects, getProjectFilterId, allProjectsSelected, hasPermission } = useWorkspace();
  const projectFilterId = getProjectFilterId();

  const [placements, setPlacements] = useState<Placement[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [includeArchived, setIncludeArchived] = useState(false);
  const [sortField, setSortField] = useState<SortField | null>(null);
  const [sortOrder, setSortOrder] = useState<SortOrder>(null);

  // Aggregation settings
  const [aggCost, setAggCost] = useState<AggFunc>("sum");
  const [aggSubs, setAggSubs] = useState<AggFunc>("sum");
  const [aggViews, setAggViews] = useState<AggFunc>("sum");
  const [aggCps, setAggCps] = useState<AggFunc>("avg");
  const [aggCpm, setAggCpm] = useState<AggFunc>("avg");

  const canWrite = hasPermission("placements_write");

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

  const loadPlacements = async () => {
    try {
      setLoading(true);
      const response = await demoAwarePlacementsApi.list(workspaceId, {
        project_id: projectFilterId,
        include_archived: includeArchived,
        size: 100,
      });
      setPlacements(response.items);
    } catch (err) {
      console.error("Failed to load placements:", err);
    } finally {
      setLoading(false);
    }
  };

  // Handle sort
  const handleSort = (field: SortField) => {
    if (sortField === field) {
      if (sortOrder === "asc") {
        setSortOrder("desc");
      } else if (sortOrder === "desc") {
        setSortField(null);
        setSortOrder(null);
      } else {
        setSortOrder("asc");
      }
    } else {
      setSortField(field);
      setSortOrder("asc");
    }
  };

  const getSortIcon = (field: SortField) => {
    if (sortField !== field) return <ArrowUpDown className="h-4 w-4 ml-1" />;
    if (sortOrder === "asc") return <ArrowUp className="h-4 w-4 ml-1" />;
    if (sortOrder === "desc") return <ArrowDown className="h-4 w-4 ml-1" />;
    return <ArrowUpDown className="h-4 w-4 ml-1" />;
  };

  // Filter and sort
  const filteredPlacements = useMemo(() => {
    return placements
      .filter(
        (p) =>
          p.placement_channel_title.toLowerCase().includes(search.toLowerCase()) ||
          p.creative_name.toLowerCase().includes(search.toLowerCase())
      )
      .sort((a, b) => {
        if (!sortField || !sortOrder) return 0;

        let aVal: number | string = 0;
        let bVal: number | string = 0;

        switch (sortField) {
          case "date":
            return sortOrder === "asc"
              ? new Date(a.placement_date).getTime() - new Date(b.placement_date).getTime()
              : new Date(b.placement_date).getTime() - new Date(a.placement_date).getTime();
          case "cost":
            aVal = a.cost ?? 0;
            bVal = b.cost ?? 0;
            break;
          case "subscriptions":
            aVal = a.subscriptions_count;
            bVal = b.subscriptions_count;
            break;
          case "views":
            aVal = a.views_count ?? 0;
            bVal = b.views_count ?? 0;
            break;
          case "cps":
            aVal = calculateCPS(a.cost, a.subscriptions_count) ?? 0;
            bVal = calculateCPS(b.cost, b.subscriptions_count) ?? 0;
            break;
          case "cpm":
            aVal = calculateCPM(a.cost, a.views_count) ?? 0;
            bVal = calculateCPM(b.cost, b.views_count) ?? 0;
            break;
          case "status":
            aVal = a.status;
            bVal = b.status;
            return sortOrder === "asc"
              ? aVal.localeCompare(bVal)
              : bVal.localeCompare(aVal);
        }

        return sortOrder === "asc"
          ? (aVal as number) - (bVal as number)
          : (bVal as number) - (aVal as number);
      });
  }, [placements, search, sortField, sortOrder]);

  // Calculate totals with aggregation functions
  const totals = useMemo(() => {
    const costs = filteredPlacements.map((p) => p.cost).filter((c): c is number => c !== null);
    const subs = filteredPlacements.map((p) => p.subscriptions_count);
    const views = filteredPlacements.map((p) => p.views_count).filter((v): v is number => v !== null);
    const cpsValues = filteredPlacements
      .map((p) => calculateCPS(p.cost, p.subscriptions_count))
      .filter((c): c is number => c !== null);
    const cpmValues = filteredPlacements
      .map((p) => calculateCPM(p.cost, p.views_count))
      .filter((c): c is number => c !== null);

    return {
      cost: aggregationFunctions[aggCost].fn(costs),
      subscriptions: aggregationFunctions[aggSubs].fn(subs),
      views: aggregationFunctions[aggViews].fn(views),
      cps: aggregationFunctions[aggCps].fn(cpsValues),
      cpm: aggregationFunctions[aggCpm].fn(cpmValues),
    };
  }, [filteredPlacements, aggCost, aggSubs, aggViews, aggCps, aggCpm]);

  // Export handlers
  const handleExport = useCallback(
    (format: "csv" | "excel" | "txt") => {
      const filename = `placements_${new Date().toISOString().split("T")[0]}`;
      switch (format) {
        case "csv":
          exportToCSV(filteredPlacements, filename);
          break;
        case "excel":
          exportToExcel(filteredPlacements, filename);
          break;
        case "txt":
          exportToTxt(filteredPlacements, filename);
          break;
      }
    },
    [filteredPlacements]
  );

  // Aggregation selector component
  const AggSelector = ({
    value,
    onChange,
  }: {
    value: AggFunc;
    onChange: (v: AggFunc) => void;
  }) => (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="ghost" size="icon" className="h-5 w-5 ml-1 opacity-50 hover:opacity-100">
          <span className="text-[10px] font-mono">f</span>
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuLabel>Функция</DropdownMenuLabel>
        {(Object.keys(aggregationFunctions) as AggFunc[]).map((key) => (
          <DropdownMenuItem
            key={key}
            onClick={() => onChange(key)}
            className={value === key ? "bg-accent" : ""}
          >
            {aggregationFunctions[key].label}
          </DropdownMenuItem>
        ))}
      </DropdownMenuContent>
    </DropdownMenu>
  );

  return (
    <TooltipProvider>
      <DashboardHeader
        breadcrumbs={[
          { label: "Главная", href: `/dashboard/${workspaceId}` },
          { label: "Размещения" },
        ]}
      />

      <div className="flex flex-1 flex-col gap-4 p-4 pt-0 mt-4">
        <div className="flex items-center justify-between">
          <div>
            <h1 className="text-2xl font-bold tracking-tight">Размещения</h1>
            <p className="text-muted-foreground">
              {filteredPlacements.length} размещений
            </p>
          </div>
          <div className="flex items-center gap-2">
            {/* Export Button */}
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Button variant="outline">
                  <Download className="h-4 w-4 mr-2" />
                  Экспорт
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end">
                <DropdownMenuItem onClick={() => handleExport("excel")}>
                  <FileSpreadsheet className="h-4 w-4 mr-2" />
                  Excel (.xls)
                </DropdownMenuItem>
                <DropdownMenuItem onClick={() => handleExport("csv")}>
                  <FileText className="h-4 w-4 mr-2" />
                  CSV
                </DropdownMenuItem>
                <DropdownMenuItem onClick={() => handleExport("txt")}>
                  <FileText className="h-4 w-4 mr-2" />
                  Текст (.txt)
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
            {canWrite && (
              <Button asChild>
                <Link href={`/dashboard/${workspaceId}/placements/new`}>
                  <Plus className="h-4 w-4 mr-2" />
                  Создать размещение
                </Link>
              </Button>
            )}
          </div>
        </div>

        <div className="flex items-center gap-4">
          <div className="relative flex-1 max-w-sm">
            <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
            <Input
              placeholder="Поиск по каналу или креативу..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="pl-10"
            />
          </div>
          <div className="flex items-center gap-2">
            <Checkbox
              id="include-archived"
              checked={includeArchived}
              onCheckedChange={(checked) => setIncludeArchived(checked === true)}
            />
            <Label htmlFor="include-archived" className="text-sm cursor-pointer">
              Показать архивные
            </Label>
          </div>
        </div>

        {loading ? (
          <div className="flex items-center justify-center py-12">
            <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
          </div>
        ) : filteredPlacements.length === 0 ? (
          <Card>
            <CardContent className="flex flex-col items-center justify-center py-12">
              <ShoppingCart 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 mb-4">
                {search ? "Ничего не найдено по вашему запросу" : "Создайте первое размещение"}
              </p>
              {canWrite && !search && (
                <Button asChild>
                  <Link href={`/dashboard/${workspaceId}/placements/new`}>
                    <Plus className="h-4 w-4 mr-2" />
                    Создать размещение
                  </Link>
                </Button>
              )}
            </CardContent>
          </Card>
        ) : (
          <Card>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Канал</TableHead>
                  <TableHead>Креатив</TableHead>
                  <TableHead>
                    <Button
                      variant="ghost"
                      size="sm"
                      className="-ml-3 h-8"
                      onClick={() => handleSort("date")}
                    >
                      Дата
                      {getSortIcon("date")}
                    </Button>
                  </TableHead>
                  <TableHead>
                    <Button
                      variant="ghost"
                      size="sm"
                      className="-ml-3 h-8"
                      onClick={() => handleSort("cost")}
                    >
                      Стоимость
                      {getSortIcon("cost")}
                    </Button>
                  </TableHead>
                  <TableHead>
                    <Button
                      variant="ghost"
                      size="sm"
                      className="-ml-3 h-8"
                      onClick={() => handleSort("subscriptions")}
                    >
                      Подписки
                      {getSortIcon("subscriptions")}
                    </Button>
                  </TableHead>
                  <TableHead>
                    <Button
                      variant="ghost"
                      size="sm"
                      className="-ml-3 h-8"
                      onClick={() => handleSort("views")}
                    >
                      Просмотры
                      {getSortIcon("views")}
                    </Button>
                  </TableHead>
                  <TableHead>
                    <div className="flex items-center">
                      <Button
                        variant="ghost"
                        size="sm"
                        className="-ml-3 h-8"
                        onClick={() => handleSort("cps")}
                      >
                        CPS
                        {getSortIcon("cps")}
                      </Button>
                      <Tooltip>
                        <TooltipTrigger asChild>
                          <Info className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
                        </TooltipTrigger>
                        <TooltipContent>Cost Per Subscription</TooltipContent>
                      </Tooltip>
                    </div>
                  </TableHead>
                  <TableHead>
                    <div className="flex items-center">
                      <Button
                        variant="ghost"
                        size="sm"
                        className="-ml-3 h-8"
                        onClick={() => handleSort("cpm")}
                      >
                        CPM
                        {getSortIcon("cpm")}
                      </Button>
                      <Tooltip>
                        <TooltipTrigger asChild>
                          <Info className="h-3.5 w-3.5 text-muted-foreground cursor-help" />
                        </TooltipTrigger>
                        <TooltipContent>Cost Per Mille (1000 views)</TooltipContent>
                      </Tooltip>
                    </div>
                  </TableHead>
                  <TableHead>
                    <Button
                      variant="ghost"
                      size="sm"
                      className="-ml-3 h-8"
                      onClick={() => handleSort("status")}
                    >
                      Статус
                      {getSortIcon("status")}
                    </Button>
                  </TableHead>
                  <TableHead className="w-[50px]"></TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {filteredPlacements.map((placement) => {
                  const cps = calculateCPS(placement.cost, placement.subscriptions_count);
                  const cpm = calculateCPM(placement.cost, placement.views_count);

                  return (
                    <TableRow key={placement.id}>
                      <TableCell>
                        <div className="font-medium">{placement.placement_channel_title}</div>
                      </TableCell>
                      <TableCell>
                        <div className="text-sm">{placement.creative_name}</div>
                      </TableCell>
                      <TableCell>{formatDate(placement.placement_date)}</TableCell>
                      <TableCell>{formatCurrency(placement.cost)}</TableCell>
                      <TableCell>{formatNumber(placement.subscriptions_count)}</TableCell>
                      <TableCell>{formatNumber(placement.views_count ?? null)}</TableCell>
                      <TableCell>{cps ? formatCurrency(cps) : "—"}</TableCell>
                      <TableCell>{cpm ? formatCurrency(cpm) : "—"}</TableCell>
                      <TableCell>
                        <Badge
                          variant={placement.status === "active" ? "default" : "secondary"}
                        >
                          {placement.status === "active" ? "Активен" : "Архив"}
                        </Badge>
                      </TableCell>
                      <TableCell>
                        <DropdownMenu>
                          <DropdownMenuTrigger asChild>
                            <Button variant="ghost" size="icon">
                              <MoreHorizontal className="h-4 w-4" />
                            </Button>
                          </DropdownMenuTrigger>
                          <DropdownMenuContent align="end">
                            <DropdownMenuItem asChild>
                              <Link href={`/dashboard/${workspaceId}/placements/${placement.id}`}>
                                <Eye className="h-4 w-4 mr-2" />
                                Подробнее
                              </Link>
                            </DropdownMenuItem>
                            {placement.ad_post_url && (
                              <DropdownMenuItem asChild>
                                <a
                                  href={placement.ad_post_url}
                                  target="_blank"
                                  rel="noopener noreferrer"
                                >
                                  <ExternalLink className="h-4 w-4 mr-2" />
                                  Открыть пост
                                </a>
                              </DropdownMenuItem>
                            )}
                          </DropdownMenuContent>
                        </DropdownMenu>
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
              {/* Totals Row */}
              <TableFooter>
                <TableRow className="bg-muted/50 font-medium">
                  <TableCell colSpan={3}>
                    <span className="text-muted-foreground">Итого</span>
                  </TableCell>
                  <TableCell>
                    <div className="flex items-center">
                      {formatCurrency(totals.cost)}
                      <AggSelector value={aggCost} onChange={setAggCost} />
                    </div>
                  </TableCell>
                  <TableCell>
                    <div className="flex items-center">
                      {formatNumber(totals.subscriptions)}
                      <AggSelector value={aggSubs} onChange={setAggSubs} />
                    </div>
                  </TableCell>
                  <TableCell>
                    <div className="flex items-center">
                      {formatNumber(totals.views)}
                      <AggSelector value={aggViews} onChange={setAggViews} />
                    </div>
                  </TableCell>
                  <TableCell>
                    <div className="flex items-center">
                      {totals.cps ? formatCurrency(totals.cps) : "—"}
                      <AggSelector value={aggCps} onChange={setAggCps} />
                    </div>
                  </TableCell>
                  <TableCell>
                    <div className="flex items-center">
                      {totals.cpm ? formatCurrency(totals.cpm) : "—"}
                      <AggSelector value={aggCpm} onChange={setAggCpm} />
                    </div>
                  </TableCell>
                  <TableCell colSpan={2}></TableCell>
                </TableRow>
              </TableFooter>
            </Table>
          </Card>
        )}
      </div>
    </TooltipProvider>
  );
}
