import { useState, useEffect, useMemo } from "react";
import {
  Plus,
  RefreshCw,
  Search,
  SlidersHorizontal,
  Home,
  ArrowUpDown,
  Loader2,
  MapPin,
} from "lucide-react";
import AppartCard from "./components/AppartCard";
import AddModal from "./components/AddModal";
import { fetchAnnonces, addAnnonce, deleteAnnonce } from "./api";

const SORT_OPTIONS = [
  { value: "prix_asc", label: "Prix croissant" },
  { value: "prix_desc", label: "Prix decroissant" },
  { value: "surface_desc", label: "Surface decroissante" },
  { value: "note_desc", label: "Meilleure note" },
  { value: "recent", label: "Plus recent" },
];

const DATE_RANGE_OPTIONS = [
  { value: "", label: "Date: Toutes" },
  { value: "today", label: "Aujourd'hui" },
  { value: "yesterday", label: "Hier" },
  { value: "last7", label: "7 derniers jours" },
  { value: "last30", label: "30 derniers jours" },
];

const parseDate = (value) => {
  if (!value) return null;

  const toDate = (input) => {
    const date = new Date(input);
    return Number.isNaN(date.getTime()) ? null : date;
  };

  let date = value instanceof Date ? value : null;

  if (!date && (typeof value === "number" || typeof value === "string")) {
    date = toDate(value);

    if (!date && typeof value === "string") {
      const trimmed = value.trim();
      const dayMatch = trimmed.match(/^([0-9]{1,2})[\/\-]([0-9]{1,2})[\/\-]([0-9]{2,4})$/);

      if (dayMatch) {
        const [, day, month, year] = dayMatch;
        const normalizedYear = year.length === 2 ? `20${year}` : year;
        date = toDate(`${normalizedYear.padStart(4, "0")}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`);
      } else {
        const monthMatch = trimmed.match(/^([0-9]{1,2})[\/\-]([0-9]{2,4})$/);
        if (monthMatch) {
          const [, month, year] = monthMatch;
          const normalizedYear = year.length === 2 ? `20${year}` : year;
          date = toDate(`${normalizedYear.padStart(4, "0")}-${month.padStart(2, "0")}-01`);
        }
      }
    }
  }

  return date;
};

const matchesDateRange = (annonce, range) => {
  if (!range) return true;

  const today = new Date();
  const startOfToday = new Date(today.getFullYear(), today.getMonth(), today.getDate());
  const startOfTomorrow = new Date(startOfToday);
  startOfTomorrow.setDate(startOfTomorrow.getDate() + 1);

  let start = null;
  let end = null;

  switch (range) {
    case "today":
      start = startOfToday;
      end = startOfTomorrow;
      break;
    case "yesterday": {
      const startOfYesterday = new Date(startOfToday);
      startOfYesterday.setDate(startOfYesterday.getDate() - 1);
      start = startOfYesterday;
      end = startOfToday;
      break;
    }
    case "last7": {
      start = new Date(startOfToday);
      start.setDate(start.getDate() - 6);
      end = startOfTomorrow;
      break;
    }
    case "last30": {
      start = new Date(startOfToday);
      start.setDate(start.getDate() - 29);
      end = startOfTomorrow;
      break;
    }
    default:
      return true;
  }

  const dates = [parseDate(annonce.DATE_DISPO), parseDate(annonce.createdAt)].filter(Boolean);
  if (!dates.length) return false;
  return dates.some((date) => date >= start && date < end);
};

function App() {
  const [annonces, setAnnonces] = useState([]);
  const [loading, setLoading] = useState(true);
  const [showAdd, setShowAdd] = useState(false);
  const [search, setSearch] = useState("");
  const [sort, setSort] = useState("recent");
  const [filters, setFilters] = useState({
    meuble: null,
    parking: null,
    balcon: null,
    maxPrix: "",
    minSurface: "",
    dateRange: "",
  });
  const [showFilters, setShowFilters] = useState(false);

  const load = async () => {
    setLoading(true);
    try {
      const data = await fetchAnnonces();
      setAnnonces(data);
    } catch (err) {
      console.error("Erreur chargement:", err);
    }
    setLoading(false);
  };

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

  const handleAdd = async (form) => {
    await addAnnonce(form);
    await load();
  };

  const handleDelete = async (id) => {
    await deleteAnnonce(id);
    await load();
  };

  const existingUrls = useMemo(
    () => annonces.map((a) => a.URL),
    [annonces]
  );

  const filtered = useMemo(() => {
    let list = [...annonces];

    if (search.trim()) {
      const q = search.toLowerCase();
      list = list.filter(
        (a) =>
          a.ADDRESS?.toLowerCase().includes(q) ||
          a.URL?.toLowerCase().includes(q) ||
          a.CHARGES?.toLowerCase().includes(q)
      );
    }

    if (filters.meuble !== null) {
      list = list.filter((a) => a.MEUBLE === filters.meuble);
    }
    if (filters.parking !== null) {
      list = list.filter((a) => a.PARKING === filters.parking);
    }
    if (filters.balcon !== null) {
      list = list.filter((a) => a.BALCON === filters.balcon);
    }
    if (filters.maxPrix) {
      list = list.filter((a) => a.PRIX <= parseFloat(filters.maxPrix));
    }
    if (filters.minSurface) {
      list = list.filter((a) => a.SURFACE >= parseInt(filters.minSurface));
    }
    if (filters.dateRange) {
      list = list.filter((a) => matchesDateRange(a, filters.dateRange));
    }

    switch (sort) {
      case "prix_asc":
        list.sort((a, b) => a.PRIX - b.PRIX);
        break;
      case "prix_desc":
        list.sort((a, b) => b.PRIX - a.PRIX);
        break;
      case "surface_desc":
        list.sort((a, b) => b.SURFACE - a.SURFACE);
        break;
      case "note_desc":
        list.sort(
          (a, b) =>
            (b.NOTE_P || 0) + (b.NOTE_A || 0) - ((a.NOTE_P || 0) + (a.NOTE_A || 0))
        );
        break;
      case "recent":
      default:
        list.sort(
          (a, b) => new Date(b.createdAt) - new Date(a.createdAt)
        );
    }

    return list;
  }, [annonces, search, sort, filters]);

  const activeFilterCount = [
    filters.meuble !== null,
    filters.parking !== null,
    filters.balcon !== null,
    !!filters.maxPrix,
    !!filters.minSurface,
    !!filters.dateRange,
  ].filter(Boolean).length;

  const stats = useMemo(() => {
    if (!annonces.length) return null;
    const prices = annonces.map((a) => a.PRIX ?? 0).filter((p) => p > 0);
    if (!prices.length) return { count: annonces.length, avgPrix: 0, minPrix: 0, maxPrix: 0 };
    return {
      count: annonces.length,
      avgPrix: (prices.reduce((s, p) => s + p, 0) / prices.length).toFixed(0),
      minPrix: Math.min(...prices).toFixed(0),
      maxPrix: Math.max(...prices).toFixed(0),
    };
  }, [annonces]);

  return (
    <div className="min-h-screen bg-sand-50">
      {/* Header */}
      <header className="sticky top-0 z-40 bg-warm-50/90 backdrop-blur-md border-b border-warm-200/50">
        <div className="max-w-6xl mx-auto px-5 py-4">
          <div className="flex items-center justify-between mb-4">
            <div className="flex items-center gap-3">
              <div className="w-10 h-10 bg-warm-400 rounded-2xl flex items-center justify-center shadow-sm">
                <Home size={18} className="text-white" />
              </div>
              <div>
                <h1 className="text-xl font-bold text-sand-900 tracking-tight">
                  Appart Nantes
                </h1>
                <p className="text-xs text-sand-500">
                  Paulin & Agathe
                  {stats && (
                    <span className="ml-1.5 text-sand-400">
                      -- {stats.count} annonce{stats.count > 1 ? "s" : ""} | moy.{" "}
                      {stats.avgPrix} EUR | {stats.minPrix} - {stats.maxPrix} EUR
                    </span>
                  )}
                </p>
              </div>
            </div>

            <div className="flex items-center gap-2">
              <button
                onClick={load}
                disabled={loading}
                className="p-2.5 rounded-xl border border-sand-200 hover:bg-sand-100 transition-colors text-sand-500 disabled:opacity-50"
                title="Rafraichir"
              >
                <RefreshCw
                  size={16}
                  className={loading ? "animate-spin" : ""}
                />
              </button>
              <button
                onClick={() => setShowAdd(true)}
                className="flex items-center gap-1.5 px-4 py-2.5 bg-warm-500 text-white rounded-xl text-sm font-semibold hover:bg-warm-600 transition-colors shadow-sm"
              >
                <Plus size={16} />
                <span className="hidden sm:inline">Ajouter</span>
              </button>
            </div>
          </div>

          {/* Search + Sort + Filters toggle */}
          <div className="flex items-center gap-2">
            <div className="flex-1 relative">
              <Search
                size={15}
                className="absolute left-3.5 top-1/2 -translate-y-1/2 text-sand-400"
              />
              <input
                type="text"
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                placeholder="Rechercher par adresse..."
                className="w-full pl-10 pr-4 py-2.5 text-sm border border-sand-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-warm-300/50 focus:border-warm-300 bg-white/80 text-sand-800 placeholder:text-sand-400"
              />
            </div>

            <div className="relative">
              <ArrowUpDown
                size={14}
                className="absolute left-3 top-1/2 -translate-y-1/2 text-sand-400 pointer-events-none"
              />
              <select
                value={sort}
                onChange={(e) => setSort(e.target.value)}
                className="pl-9 pr-4 py-2.5 text-sm border border-sand-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-warm-300/50 focus:border-warm-300 bg-white/80 text-sand-700 appearance-none cursor-pointer"
              >
                {SORT_OPTIONS.map((o) => (
                  <option key={o.value} value={o.value}>
                    {o.label}
                  </option>
                ))}
              </select>
            </div>

            <button
              onClick={() => setShowFilters(!showFilters)}
              className={`relative p-2.5 rounded-xl border transition-colors ${
                showFilters || activeFilterCount
                  ? "border-warm-400 bg-warm-50 text-warm-600"
                  : "border-sand-200 hover:bg-sand-100 text-sand-500"
              }`}
            >
              <SlidersHorizontal size={16} />
              {activeFilterCount > 0 && (
                <span className="absolute -top-1 -right-1 w-4 h-4 bg-warm-500 text-white text-[10px] font-bold rounded-full flex items-center justify-center">
                  {activeFilterCount}
                </span>
              )}
            </button>
          </div>

          {/* Filters panel */}
          {showFilters && (
            <div className="mt-3 p-3.5 bg-white/60 rounded-xl border border-sand-200 flex flex-wrap items-center gap-3">
              {[
                { key: "meuble", label: "Meuble" },
                { key: "parking", label: "Parking" },
                { key: "balcon", label: "Balcon" },
              ].map(({ key, label }) => (
                <div key={key} className="flex items-center gap-1.5">
                  <span className="text-xs text-sand-600 font-medium">{label}</span>
                  <select
                    value={
                      filters[key] === null
                        ? ""
                        : filters[key]
                        ? "true"
                        : "false"
                    }
                    onChange={(e) =>
                      setFilters((f) => ({
                        ...f,
                        [key]:
                          e.target.value === ""
                            ? null
                            : e.target.value === "true",
                      }))
                    }
                    className="px-2 py-1 text-xs border border-sand-200 rounded-lg bg-white text-sand-700 focus:outline-none focus:ring-1 focus:ring-warm-300"
                  >
                    <option value="">Tous</option>
                    <option value="true">Oui</option>
                    <option value="false">Non</option>
                  </select>
                </div>
              ))}

              <div className="flex items-center gap-1.5">
                <span className="text-xs text-sand-600 font-medium">Prix max</span>
                <input
                  type="number"
                  value={filters.maxPrix}
                  onChange={(e) =>
                    setFilters((f) => ({ ...f, maxPrix: e.target.value }))
                  }
                  placeholder="EUR"
                  className="w-20 px-2 py-1 text-xs border border-sand-200 rounded-lg bg-white text-sand-700 focus:outline-none focus:ring-1 focus:ring-warm-300"
                />
              </div>

              <div className="flex items-center gap-1.5">
                <span className="text-xs text-sand-600 font-medium">Surface min</span>
                <input
                  type="number"
                  value={filters.minSurface}
                  onChange={(e) =>
                    setFilters((f) => ({ ...f, minSurface: e.target.value }))
                  }
                  placeholder="m2"
                  className="w-20 px-2 py-1 text-xs border border-sand-200 rounded-lg bg-white text-sand-700 focus:outline-none focus:ring-1 focus:ring-warm-300"
                />
              </div>

              <div className="flex items-center gap-1.5">
                <span className="text-xs text-sand-600 font-medium">Date</span>
                <select
                  value={filters.dateRange}
                  onChange={(e) =>
                    setFilters((f) => ({
                      ...f,
                      dateRange: e.target.value,
                    }))
                  }
                  className="px-2 py-1 text-xs border border-sand-200 rounded-lg bg-white text-sand-700 focus:outline-none focus:ring-1 focus:ring-warm-300"
                >
                  {DATE_RANGE_OPTIONS.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </select>
              </div>

              {activeFilterCount > 0 && (
                <button
                  onClick={() =>
                    setFilters({
                      meuble: null,
                      parking: null,
                      balcon: null,
                      maxPrix: "",
                      minSurface: "",
                      dateRange: "",
                    })
                  }
                  className="text-xs text-warm-600 hover:text-warm-800 font-semibold"
                >
                  Reinitialiser
                </button>
              )}
            </div>
          )}
        </div>
      </header>

      {/* Content */}
      <main className="max-w-6xl mx-auto px-5 py-8">
        {loading && !annonces.length ? (
          <div className="flex flex-col items-center justify-center py-24 text-sand-400">
            <Loader2 size={28} className="animate-spin mb-3 text-warm-400" />
            <p className="text-sm text-sand-500">Chargement des annonces...</p>
          </div>
        ) : filtered.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-24">
            <div className="w-16 h-16 bg-warm-100 rounded-full flex items-center justify-center mb-4">
              <MapPin size={28} className="text-warm-400" />
            </div>
            <p className="text-sm font-semibold text-sand-700">
              Aucune annonce trouvee
            </p>
            <p className="text-xs mt-1 text-sand-400">
              {annonces.length
                ? "Essaie de modifier tes filtres"
                : "Ajoute ta premiere annonce !"}
            </p>
          </div>
        ) : (
          <div className="grid grid-cols-1 md:grid-cols-2 gap-5 items-start">
            {filtered.map((a, idx) => (
              <AppartCard
                key={a.id ?? idx}
                annonce={a}
                onDelete={handleDelete}
                onUpdated={load}
              />
            ))}
          </div>
        )}
      </main>

      {/* Add modal */}
      <AddModal
        open={showAdd}
        onClose={() => setShowAdd(false)}
        onSubmit={handleAdd}
        existingUrls={existingUrls}
      />
    </div>
  );
}

export default App;
