"use client";

import { useState } from "react";
import type { FactorContribution } from "@/types/site-finder";

// ---------------------------------------------------------------------------
// Color mapping per category
// ---------------------------------------------------------------------------

const CATEGORY_COLORS: Record<string, string> = {
  school: "#1d4ed8",
  kindergarten: "#1d4ed8",
  pharmacy: "#10b981",
  hospital: "#f59e0b",
  shop_mall: "#a855f7",
  shop_supermarket: "#a855f7",
  shop_small: "#c084fc",
  park: "#16a34a",
  tram_stop: "#dc2626",
  bus_stop: "#6b7280",
  metro_stop: "#1e40af",
  custom: "#f97316", // custom POIs — orange with border
};

function categoryColor(category: string): string {
  return CATEGORY_COLORS[category] ?? "#94a3b8";
}

// ---------------------------------------------------------------------------
// Props
// ---------------------------------------------------------------------------

interface Props {
  /** Full factor breakdown from ParcelAnalysis.score_breakdown_detailed */
  breakdown: FactorContribution[];
  /** Factor names that come from custom POIs (to highlight visually) */
  customPoiFactors?: string[];
}

// ---------------------------------------------------------------------------
// Aggregation helpers
// ---------------------------------------------------------------------------

interface CategoryAgg {
  category: string;
  category_ru: string;
  contribution: number;
  count: number;
  isCustom: boolean;
}

function aggregateByCategory(
  items: FactorContribution[],
  customFactors: Set<string>,
): CategoryAgg[] {
  const map = new Map<string, CategoryAgg>();

  for (const item of items) {
    const key = item.category;
    const existing = map.get(key);
    if (existing) {
      existing.contribution += item.contribution;
      existing.count += 1;
      if (customFactors.has(item.factor)) existing.isCustom = true;
    } else {
      map.set(key, {
        category: key,
        category_ru: item.category_ru,
        contribution: item.contribution,
        count: 1,
        isCustom: customFactors.has(item.factor),
      });
    }
  }

  return [...map.values()].sort((a, b) => b.contribution - a.contribution);
}

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

export function ScoreBreakdownStackedBar({
  breakdown,
  customPoiFactors = [],
}: Props) {
  const [groupBy, setGroupBy] = useState<"category" | "source">("category");
  const [hoveredCat, setHoveredCat] = useState<string | null>(null);

  const customSet = new Set(customPoiFactors);

  // Aggregate by category (or source as fallback label when groupBy=source)
  const aggregated = aggregateByCategory(breakdown, customSet);

  // Split positive and negative for stacked bar
  const positives = aggregated.filter((a) => a.contribution > 0);
  const negatives = aggregated.filter((a) => a.contribution < 0);

  const totalPositive = positives.reduce((s, a) => s + a.contribution, 0) || 1;
  const totalNegative =
    Math.abs(negatives.reduce((s, a) => s + a.contribution, 0)) || 1;

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

  const fmtV = (v: number) => `${v >= 0 ? "+" : ""}${v.toFixed(2)}`;

  // Group-by toggle (source mode uses factor field as key — simpler visual)
  const sourceAgg =
    groupBy === "source"
      ? (() => {
          const sm = new Map<string, { contribution: number; count: number }>();
          for (const item of breakdown) {
            const key = item.factor;
            const ex = sm.get(key);
            if (ex) {
              ex.contribution += item.contribution;
              ex.count += 1;
            } else {
              sm.set(key, { contribution: item.contribution, count: 1 });
            }
          }
          return [...sm.entries()]
            .map(([k, v]) => ({ factor: k, ...v }))
            .sort((a, b) => b.contribution - a.contribution)
            .slice(0, 10);
        })()
      : null;

  return (
    <div
      style={{
        border: "1px solid #e5e7eb",
        borderRadius: 10,
        padding: "14px 18px",
        background: "#fff",
        display: "flex",
        flexDirection: "column",
        gap: 14,
      }}
    >
      {/* Header + toggle */}
      <div
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          flexWrap: "wrap",
          gap: 8,
        }}
      >
        <div
          style={{
            fontSize: 12,
            fontWeight: 600,
            color: "#6b7280",
            textTransform: "uppercase",
            letterSpacing: "0.05em",
          }}
        >
          Вклад по категориям
        </div>
        <div style={{ display: "flex", gap: 6, fontSize: 12 }}>
          <button
            type="button"
            onClick={() => setGroupBy("category")}
            style={{
              padding: "3px 10px",
              borderRadius: 5,
              border: "1px solid",
              borderColor: groupBy === "category" ? "#1d4ed8" : "#d1d5db",
              background: groupBy === "category" ? "#dbeafe" : "#f9fafb",
              color: groupBy === "category" ? "#1d4ed8" : "#6b7280",
              cursor: "pointer",
              fontWeight: groupBy === "category" ? 600 : 400,
            }}
          >
            По категории
          </button>
          <button
            type="button"
            onClick={() => setGroupBy("source")}
            style={{
              padding: "3px 10px",
              borderRadius: 5,
              border: "1px solid",
              borderColor: groupBy === "source" ? "#1d4ed8" : "#d1d5db",
              background: groupBy === "source" ? "#dbeafe" : "#f9fafb",
              color: groupBy === "source" ? "#1d4ed8" : "#6b7280",
              cursor: "pointer",
              fontWeight: groupBy === "source" ? 600 : 400,
            }}
          >
            По фактору
          </button>
        </div>
      </div>

      {/* Stacked horizontal bar — positive contributions */}
      {groupBy === "category" && positives.length > 0 && (
        <div>
          <div style={{ fontSize: 11, color: "#6b7280", marginBottom: 4 }}>
            Положительный вклад
          </div>
          <div
            style={{
              display: "flex",
              height: 28,
              borderRadius: 5,
              overflow: "hidden",
              border: "1px solid #e5e7eb",
            }}
            role="img"
            aria-label="Stacked bar: положительный вклад по категориям"
          >
            {positives.map((agg) => {
              const widthPct = (agg.contribution / totalPositive) * 100;
              const color = agg.isCustom
                ? CATEGORY_COLORS.custom
                : categoryColor(agg.category);
              const isHovered = hoveredCat === agg.category;
              return (
                <div
                  key={agg.category}
                  style={{
                    width: `${widthPct}%`,
                    background: color,
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    fontSize: 11,
                    color: "#fff",
                    fontWeight: 500,
                    overflow: "hidden",
                    whiteSpace: "nowrap",
                    cursor: "default",
                    outline: agg.isCustom ? "2px dashed #ea580c" : "none",
                    outlineOffset: -2,
                    opacity: hoveredCat && !isHovered ? 0.6 : 1,
                    transition: "opacity 0.15s",
                  }}
                  title={`${agg.category_ru}${agg.isCustom ? " (custom)" : ""}: ${fmtV(agg.contribution)}`}
                  onMouseEnter={() => setHoveredCat(agg.category)}
                  onMouseLeave={() => setHoveredCat(null)}
                >
                  {widthPct >= 12 ? `${Math.round(widthPct)}%` : ""}
                </div>
              );
            })}
          </div>

          {/* Negative bar */}
          {negatives.length > 0 && (
            <>
              <div
                style={{
                  fontSize: 11,
                  color: "#6b7280",
                  marginTop: 10,
                  marginBottom: 4,
                }}
              >
                Снижают балл
              </div>
              <div
                style={{
                  display: "flex",
                  height: 20,
                  borderRadius: 5,
                  overflow: "hidden",
                  border: "1px solid #fca5a5",
                }}
              >
                {negatives.map((agg) => {
                  const widthPct =
                    (Math.abs(agg.contribution) / totalNegative) * 100;
                  const color = categoryColor(agg.category);
                  return (
                    <div
                      key={agg.category}
                      style={{
                        width: `${widthPct}%`,
                        background: color,
                        opacity: 0.6,
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "center",
                        fontSize: 10,
                        color: "#fff",
                        overflow: "hidden",
                        whiteSpace: "nowrap",
                        cursor: "default",
                      }}
                      title={`${agg.category_ru}: ${fmtV(agg.contribution)}`}
                    >
                      {widthPct >= 15 ? `${Math.round(widthPct)}%` : ""}
                    </div>
                  );
                })}
              </div>
            </>
          )}

          {/* Legend */}
          <div
            style={{
              display: "flex",
              flexWrap: "wrap",
              gap: 8,
              marginTop: 10,
              fontSize: 12,
              color: "#6b7280",
            }}
          >
            {aggregated
              .filter((a) => a.contribution !== 0)
              .map((agg) => {
              const color = agg.isCustom
                ? CATEGORY_COLORS.custom
                : categoryColor(agg.category);
              return (
                <div
                  key={agg.category}
                  style={{
                    display: "flex",
                    alignItems: "center",
                    gap: 4,
                    cursor: "default",
                  }}
                  onMouseEnter={() => setHoveredCat(agg.category)}
                  onMouseLeave={() => setHoveredCat(null)}
                >
                  <span
                    style={{
                      display: "inline-block",
                      width: 10,
                      height: 10,
                      borderRadius: 2,
                      background: color,
                      outline: agg.isCustom ? "1.5px dashed #ea580c" : "none",
                      outlineOffset: 1,
                    }}
                  />
                  <span>
                    {agg.category_ru}
                    {agg.isCustom && (
                      <span
                        style={{
                          marginLeft: 3,
                          fontSize: 10,
                          color: "#ea580c",
                          fontWeight: 600,
                        }}
                      >
                        (custom)
                      </span>
                    )}
                    :{" "}
                    <strong
                      style={{
                        color: agg.contribution >= 0 ? "#16a34a" : "#dc2626",
                      }}
                    >
                      {fmtV(agg.contribution)}
                    </strong>
                  </span>
                </div>
              );
            })}
          </div>
        </div>
      )}

      {/* Source (factor) view — top 10 table */}
      {groupBy === "source" && sourceAgg && (
        <div style={{ display: "flex", flexDirection: "column", gap: 5 }}>
          {sourceAgg.map(({ factor, contribution }) => {
            const isCustom = customSet.has(factor);
            const maxAbs =
              Math.max(...sourceAgg.map((s) => Math.abs(s.contribution))) || 1;
            const barWidth = Math.min(
              100,
              (Math.abs(contribution) / maxAbs) * 100,
            );
            const color =
              contribution >= 0
                ? isCustom
                  ? CATEGORY_COLORS.custom
                  : "#16a34a"
                : "#dc2626";
            return (
              <div
                key={factor}
                style={{ display: "flex", alignItems: "center", gap: 10 }}
              >
                <div
                  style={{
                    fontSize: 12,
                    color: "#374151",
                    width: 180,
                    flexShrink: 0,
                    overflow: "hidden",
                    textOverflow: "ellipsis",
                    whiteSpace: "nowrap",
                  }}
                  title={factor}
                >
                  {isCustom && (
                    <span
                      style={{
                        fontSize: 10,
                        color: "#ea580c",
                        fontWeight: 600,
                        marginRight: 4,
                      }}
                    >
                      [custom]
                    </span>
                  )}
                  {factor}
                </div>
                <div
                  style={{
                    flex: 1,
                    height: 14,
                    background: "#f3f4f6",
                    borderRadius: 3,
                    overflow: "hidden",
                  }}
                >
                  <div
                    style={{
                      width: `${barWidth}%`,
                      height: "100%",
                      background: color,
                      borderRadius: 3,
                      outline: isCustom ? "1.5px dashed #ea580c" : "none",
                    }}
                  />
                </div>
                <div
                  style={{
                    fontSize: 12,
                    fontWeight: 600,
                    color,
                    width: 50,
                    textAlign: "right",
                    flexShrink: 0,
                    fontVariantNumeric: "tabular-nums",
                  }}
                >
                  {fmtV(contribution)}
                </div>
              </div>
            );
          })}
          {breakdown.length > 10 && (
            <div style={{ fontSize: 11, color: "#9ca3af", marginTop: 4 }}>
              Показаны топ-10 из {breakdown.length} факторов
            </div>
          )}
        </div>
      )}
    </div>
  );
}
