"use client";

import { useEffect, useMemo, useState } from "react";
import { Link, useTranslation } from "@/i18n/navigation";
import CityCard from "@/app/components/CityCard";
import CityModal from "@/app/components/CityModal";
import Footer from "@/app/components/Footer";
import { cities as fallbackCities, type City } from "@/app/data/cities";
import { apiFetch } from "@/app/lib/api-client";

type RecommendedCity = City & {
  matchScore?: number;
  matchReasons?: string[];
  idNumber?: number;
};

interface Meetup {
  id: string;
  city: string;
  emoji?: string;
  date?: string;
  time?: string;
  venue?: string;
  rsvpCount?: number;
  isUpcoming?: boolean;
}

interface NomadRoute {
  id?: string;
  slug: string;
  title: string;
  titleEn?: string;
  durationDays: number;
  budget: number;
  description: string;
  stops: string[];
  cities?: RecommendedCity[];
}

const CITY_TAGS = ["便宜", "宜居", "文化", "美食", "高速网络", "友好社区", "海滨", "都市"];
const TIMEZONES = ["UTC+8 中国", "UTC+7 东南亚", "UTC+1 欧洲", "UTC-5 美东", "UTC-8 美西", "任意"];
const VISA_OPTIONS = ["免签优先", "落地签可", "需提前办", "任意"];
const CLIMATE_OPTIONS = [
  { value: "any", label: "任意气候" },
  { value: "mild", label: "温和" },
  { value: "warm", label: "偏暖" },
  { value: "cool", label: "偏凉" },
];

function mapCity(item: Partial<RecommendedCity>, index: number): RecommendedCity {
  return {
    ...item,
    id: Number(item.idNumber || item.id || index + 1),
    name: item.name || "未知城市",
    country: item.country || "中国",
    countryEmoji: item.countryEmoji || "🇨🇳",
    overallScore: Number(item.overallScore || 0),
    costPerMonth: Number(item.costPerMonth || 0),
    internetSpeed: Number(item.internetSpeed || 0),
    safety: item.safety || "很好",
    liked: item.liked || "很好",
    temperature: Number(item.temperature || 0),
    humidity: Number(item.humidity || 0),
    nomadsNow: Number(item.nomadsNow || 0),
    description: item.description || "",
    gradientFrom: item.gradientFrom || "#ff4d4f",
    gradientTo: item.gradientTo || "#ff7a45",
    icon: item.icon || "📍",
    tags: Array.isArray(item.tags) ? item.tags : [],
  } as RecommendedCity;
}

function formatMeetupDate(date?: string, time?: string): string {
  if (!date) return time || "时间待定";
  const day = date.slice(5, 10).replace("-", "月") + "日";
  return time ? `${day} ${time.slice(0, 5)}` : day;
}

export default function DashboardPage() {
  const { t } = useTranslation("dashboard");
  const [budget, setBudget] = useState(5000);
  const [internet, setInternet] = useState(50);
  const [timezone, setTimezone] = useState("UTC+8 中国");
  const [visa, setVisa] = useState("任意");
  const [climate, setClimate] = useState("mild");
  const [selectedTags, setSelectedTags] = useState<string[]>(["宜居"]);
  const [cityModal, setCityModal] = useState<City | null>(null);
  const [baseCities, setBaseCities] = useState<RecommendedCity[]>(
    fallbackCities.map((city, index) => mapCity(city, index))
  );
  const [recommendedCities, setRecommendedCities] = useState<RecommendedCity[]>([]);
  const [meetups, setMeetups] = useState<Meetup[]>([]);
  const [routes, setRoutes] = useState<NomadRoute[]>([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    apiFetch<{ items: RecommendedCity[] }>("/api/cities")
      .then((data) => {
        if (data.items?.length) {
          setBaseCities(data.items.map(mapCity));
        }
      })
      .catch(() => setBaseCities(fallbackCities.map((city, index) => mapCity(city, index))));

    apiFetch<{ items: Meetup[] }>("/api/meetups")
      .then((data) => setMeetups((data.items || []).slice(0, 8)))
      .catch(() => setMeetups([]));

    apiFetch<{ items: NomadRoute[] }>("/api/routes")
      .then((data) => setRoutes(data.items || []))
      .catch(() => setRoutes([]));
  }, []);

  const fallbackRecommendations = useMemo(() => {
    return [...baseCities]
      .filter((city) => city.costPerMonth <= budget * 1.25 && city.internetSpeed >= internet * 0.8)
      .map((city) => ({
        ...city,
        matchScore: Math.round(city.overallScore * 20 + Math.max(0, 20 - city.costPerMonth / 500)),
        matchReasons: [
          city.costPerMonth <= budget ? "预算内" : "略超预算",
          city.internetSpeed >= internet ? "网络达标" : "需确认住处网络",
          city.nomadsNow >= 300 ? "社区活跃" : "适合安静工作",
        ],
      }))
      .sort((a, b) => (b.matchScore || 0) - (a.matchScore || 0))
      .slice(0, 12);
  }, [baseCities, budget, internet]);

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    apiFetch<{ items: RecommendedCity[] }>("/api/recommendations/next-stop", {
      method: "POST",
      body: JSON.stringify({ budget, internet, climate, tags: selectedTags, limit: 12 }),
    })
      .then((data) => {
        if (!cancelled) {
          setRecommendedCities((data.items || []).map(mapCity));
        }
      })
      .catch(() => {
        if (!cancelled) setRecommendedCities(fallbackRecommendations);
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, [budget, climate, fallbackRecommendations, internet, selectedTags]);

  const displayCities = recommendedCities.length ? recommendedCities : fallbackRecommendations;
  const bestCity = displayCities[0];
  const topCost = Math.max(...displayCities.slice(0, 6).map((city) => city.costPerMonth), 1);
  const topNomads = Math.max(...displayCities.slice(0, 6).map((city) => city.nomadsNow), 1);
  const upcomingMeetups = meetups.filter((meetup) => meetup.isUpcoming !== false).slice(0, 6);

  const toggleTag = (tag: string) => {
    setSelectedTags((prev) =>
      prev.includes(tag) ? prev.filter((item) => item !== tag) : [...prev, tag]
    );
  };

  return (
    <div className="min-h-screen bg-[#fafafa] dark:bg-gray-950">
      <div className="max-w-6xl mx-auto px-4 sm:px-6 py-8 sm:py-12">
        <div className="mb-8">
          <h1 className="text-2xl sm:text-3xl font-bold text-gray-900 dark:text-gray-100">
            {t("title")}
          </h1>
          <p className="mt-1 text-gray-500 dark:text-gray-400">{t("subtitle")}</p>
        </div>

        <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
          <aside className="lg:col-span-1 space-y-6">
            <div className="rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-4 sm:p-6">
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                {t("budget")}
              </label>
              <input
                type="range"
                min="2000"
                max="15000"
                step="500"
                value={budget}
                onChange={(event) => setBudget(Number(event.target.value))}
                className="w-full accent-[#ff4d4f]"
              />
              <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
                ¥{budget.toLocaleString()}
              </p>
            </div>

            <div className="rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-4 sm:p-6">
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                {t("timezone")}
              </label>
              <select
                value={timezone}
                onChange={(event) => setTimezone(event.target.value)}
                className="w-full rounded-lg border border-gray-200 dark:border-gray-700 px-4 py-2 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
              >
                {TIMEZONES.map((zone) => (
                  <option key={zone} value={zone}>
                    {zone}
                  </option>
                ))}
              </select>
            </div>

            <div className="rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-4 sm:p-6">
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                气候偏好
              </label>
              <select
                value={climate}
                onChange={(event) => setClimate(event.target.value)}
                className="w-full rounded-lg border border-gray-200 dark:border-gray-700 px-4 py-2 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
              >
                {CLIMATE_OPTIONS.map((option) => (
                  <option key={option.value} value={option.value}>
                    {option.label}
                  </option>
                ))}
              </select>
            </div>

            <div className="rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-4 sm:p-6">
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                {t("visa")}
              </label>
              <select
                value={visa}
                onChange={(event) => setVisa(event.target.value)}
                className="w-full rounded-lg border border-gray-200 dark:border-gray-700 px-4 py-2 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
              >
                {VISA_OPTIONS.map((option) => (
                  <option key={option} value={option}>
                    {option}
                  </option>
                ))}
              </select>
            </div>

            <div className="rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-4 sm:p-6">
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                {t("internet")}
              </label>
              <input
                type="range"
                min="30"
                max="150"
                step="10"
                value={internet}
                onChange={(event) => setInternet(Number(event.target.value))}
                className="w-full accent-[#ff4d4f]"
              />
              <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">{internet} Mbps</p>
            </div>

            <div className="rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-4 sm:p-6">
              <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-3">
                城市偏好
              </label>
              <div className="flex flex-wrap gap-2">
                {CITY_TAGS.map((tag) => (
                  <button
                    key={tag}
                    type="button"
                    onClick={() => toggleTag(tag)}
                    className={`px-3 py-1.5 rounded-full text-xs font-medium transition-colors ${
                      selectedTags.includes(tag)
                        ? "bg-[#ff4d4f] text-white"
                        : "bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700"
                    }`}
                  >
                    {tag}
                  </button>
                ))}
              </div>
            </div>

            <div className="rounded-2xl bg-gradient-to-br from-amber-50 to-orange-50 dark:from-amber-950/30 dark:to-orange-950/30 border border-amber-200 dark:border-amber-800/50 p-4">
              <p className="text-sm font-medium text-amber-800 dark:text-amber-200">
                🤖 {t("aiTip")}
              </p>
              <p className="mt-1 text-xs text-amber-700 dark:text-amber-300">
                {bestCity
                  ? `${bestCity.name} 当前匹配度最高：${(bestCity.matchReasons || []).join("、") || "综合分领先"}。`
                  : `正在按 ${timezone} / ${visa} 重新计算。`}
              </p>
            </div>
          </aside>

          <main className="lg:col-span-2">
            <div className="rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-4 sm:p-6 mb-6">
              <div className="flex items-center justify-between gap-3 mb-4">
                <h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100">
                  {t("search")}
                </h2>
                {loading && (
                  <span className="text-xs text-gray-400 dark:text-gray-500">正在计算</span>
                )}
              </div>
              <div className="grid grid-cols-2 sm:grid-cols-3 gap-3" style={{ gridAutoRows: "160px" }}>
                {displayCities.map((city, index) => (
                  <div key={`${city.slug || city.id}-${index}`} className="h-full min-h-[140px]">
                    <CityCard
                      city={city}
                      rank={index + 1}
                      onClick={() => setCityModal(city)}
                    />
                  </div>
                ))}
              </div>
              {displayCities.length === 0 && (
                <p className="text-center py-8 text-gray-500 dark:text-gray-400">{t("noMatch")}</p>
              )}
            </div>

            <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
              <section className="rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-4 min-h-40">
                <h3 className="font-medium text-gray-900 dark:text-gray-100 mb-3">
                  {t("costCurve")}
                </h3>
                <div className="space-y-3">
                  {displayCities.slice(0, 6).map((city) => (
                    <div key={`cost-${city.slug || city.id}`}>
                      <div className="mb-1 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400">
                        <span>{city.name}</span>
                        <span>¥{city.costPerMonth.toLocaleString()}/月</span>
                      </div>
                      <div className="h-2 rounded-full bg-gray-100 dark:bg-gray-800 overflow-hidden">
                        <div
                          className="h-full rounded-full bg-[#ff4d4f]"
                          style={{ width: `${Math.max(10, (city.costPerMonth / topCost) * 100)}%` }}
                        />
                      </div>
                    </div>
                  ))}
                </div>
              </section>

              <section className="rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-4 min-h-40">
                <h3 className="font-medium text-gray-900 dark:text-gray-100 mb-3">
                  {t("nomadHeatmap")}
                </h3>
                <div className="space-y-3">
                  {displayCities.slice(0, 6).map((city) => (
                    <div key={`community-${city.slug || city.id}`}>
                      <div className="mb-1 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400">
                        <span>{city.icon} {city.name}</span>
                        <span>{city.nomadsNow.toLocaleString()} 人</span>
                      </div>
                      <div className="h-2 rounded-full bg-gray-100 dark:bg-gray-800 overflow-hidden">
                        <div
                          className="h-full rounded-full bg-emerald-500"
                          style={{ width: `${Math.max(10, (city.nomadsNow / topNomads) * 100)}%` }}
                        />
                      </div>
                    </div>
                  ))}
                </div>
              </section>
            </div>

            {routes.length > 0 && (
              <section className="mt-6 rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-4">
                <div className="mb-3 flex items-center justify-between">
                  <h3 className="font-medium text-gray-900 dark:text-gray-100">推荐路线</h3>
                  <span className="text-xs text-gray-400 dark:text-gray-500">{routes.length} 条路线</span>
                </div>
                <div className="grid gap-3 sm:grid-cols-3">
                  {routes.slice(0, 3).map((route) => (
                    <Link
                      key={route.slug}
                      href={`/dashboard?route=${encodeURIComponent(route.slug)}`}
                      className="rounded-xl border border-gray-100 dark:border-gray-800 bg-gray-50 dark:bg-gray-800 p-3 hover:border-[#ff4d4f]/40 transition-colors"
                    >
                      <p className="font-semibold text-sm text-gray-900 dark:text-gray-100 line-clamp-1">
                        {route.title}
                      </p>
                      <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                        {route.durationDays} 天 · ¥{route.budget.toLocaleString()}
                      </p>
                      <p className="mt-2 text-xs text-gray-500 dark:text-gray-400 line-clamp-2">
                        {route.stops?.join(" → ") || route.description}
                      </p>
                    </Link>
                  ))}
                </div>
              </section>
            )}

            <section className="mt-6 rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 p-4">
              <h3 className="font-medium text-gray-900 dark:text-gray-100 mb-2">
                {t("nearbyEvents")}
              </h3>
              <div className="flex gap-2 overflow-x-auto pb-2">
                {(upcomingMeetups.length ? upcomingMeetups : meetups).slice(0, 6).map((meetup) => (
                  <Link
                    key={meetup.id}
                    href="/meetups"
                    className="shrink-0 px-4 py-2 rounded-xl bg-gray-100 dark:bg-gray-800 text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700"
                  >
                    {meetup.emoji || "📍"} {meetup.city} {formatMeetupDate(meetup.date, meetup.time)}
                  </Link>
                ))}
              </div>
            </section>
          </main>
        </div>
      </div>

      <CityModal
        city={cityModal}
        isOpen={!!cityModal}
        onClose={() => setCityModal(null)}
      />
      <Footer />
    </div>
  );
}
