import React, { useEffect, useMemo, useState } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/Card";
import { Button } from "../components/ui/Button";
import { Input } from "../components/ui/Input";
import { ScrollArea } from "../components/ui/ScrollArea";
import { api } from "../api/client";
import { useAppStore } from "../store/useAppStore";
import { useUiStore } from "../store/useUiStore";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "../components/ui/AlertDialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "../components/ui/Select";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
  faClockRotateLeft,
  faClock,
  faTags,
  faTrash,
  faChartBar,
  faPlus,
  faHourglassHalf,
} from "@fortawesome/free-solid-svg-icons";

const unitOptions = [
  { label: "Saat", value: "hours", seconds: 3600 },
  { label: "Gün", value: "days", seconds: 86400 },
  { label: "Hafta", value: "weeks", seconds: 604800 },
] as const;

const sortOptions = [
  { label: "İsim", value: "name" },
  { label: "Boyut", value: "size" },
  { label: "Geri Sayım", value: "countdown" },
  { label: "Tracker", value: "tracker" },
  { label: "Eklenme Tarihi", value: "addedOn" },
] as const;

const formatBytes = (value: number) => {
  if (!Number.isFinite(value)) return "0 B";
  const units = ["B", "KB", "MB", "GB", "TB"];
  let size = value;
  let unitIndex = 0;
  while (size >= 1024 && unitIndex < units.length - 1) {
    size /= 1024;
    unitIndex += 1;
  }
  return `${size.toFixed(size >= 10 ? 0 : 1)} ${units[unitIndex]}`;
};

const formatDuration = (seconds: number) => {
  if (!Number.isFinite(seconds)) return "0 sn";
  if (seconds >= 86400) {
    return `${(seconds / 86400).toFixed(1)} gün`;
  }
  if (seconds >= 3600) {
    return `${(seconds / 3600).toFixed(1)} saat`;
  }
  return `${Math.max(1, Math.round(seconds / 60))} dk`;
};

const formatCountdown = (seconds: number) => {
  if (!Number.isFinite(seconds)) return "—";
  const clamped = Math.max(0, Math.floor(seconds));
  const days = Math.floor(clamped / 86400);
  const hours = Math.floor((clamped % 86400) / 3600);
  const minutes = Math.floor((clamped % 3600) / 60);
  const secs = clamped % 60;
  const pad = (value: number) => value.toString().padStart(2, "0");
  return `${days}g ${pad(hours)}:${pad(minutes)}:${pad(secs)}`;
};

const formatAddedOn = (addedOn?: number) => {
  if (!Number.isFinite(addedOn)) return "Bilinmiyor";
  return new Date(addedOn * 1000).toLocaleString();
};

const trackerLabel = (tracker?: string) => {
  if (!tracker) return "Bilinmiyor";
  try {
    const host = new URL(tracker).hostname;
    return host.replace(/^www\./, "");
  } catch {
    return tracker;
  }
};

export const TimerPage = () => {
  const torrents = useAppStore((s) => s.torrents);
  const timerRules = useAppStore((s) => s.timerRules);
  const timerLogs = useAppStore((s) => s.timerLogs);
  const timerSummary = useAppStore((s) => s.timerSummary);
  const setTimerRules = useAppStore((s) => s.setTimerRules);
  const setTimerLogs = useAppStore((s) => s.setTimerLogs);
  const setTimerSummary = useAppStore((s) => s.setTimerSummary);

  const [selectedTags, setSelectedTags] = useState<string[]>([]);
  const [seedValue, setSeedValue] = useState(2);
  const [seedUnit, setSeedUnit] = useState<(typeof unitOptions)[number]["value"]>(
    "weeks"
  );
  const [sortKey, setSortKey] =
    useState<(typeof sortOptions)[number]["value"]>("countdown");
  const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc");
  const [deleteFiles, setDeleteFiles] = useState(true);
  const [busy, setBusy] = useState(false);
  const pushAlert = useUiStore((s) => s.pushAlert);
  const [nowTick, setNowTick] = useState(() => Date.now());

  const tagOptions = useMemo(() => {
    const tags = new Set<string>();
    torrents.forEach((torrent) => {
      const tagList = torrent.tags
        ? torrent.tags.split(",").map((tag) => tag.trim())
        : [];
      tagList.filter(Boolean).forEach((tag) => tags.add(tag));
      if (torrent.category) {
        tags.add(torrent.category);
      }
    });
    return Array.from(tags.values()).sort((a, b) => a.localeCompare(b));
  }, [torrents]);

  const rulesForDisplay = useMemo(() => {
    return [...timerRules].sort((a, b) => b.createdAt.localeCompare(a.createdAt));
  }, [timerRules]);

  const matchingTorrents = useMemo(() => {
    if (timerRules.length === 0) {
      return [];
    }
    return torrents
      .map((torrent) => {
        const tags = (torrent.tags ?? "")
          .split(",")
          .map((tag) => tag.trim().toLowerCase())
          .filter(Boolean);
        if (torrent.category) {
          tags.push(torrent.category.toLowerCase());
        }
        const addedOnMs = Number(torrent.added_on ?? 0) * 1000;
        const matchingRules = timerRules.filter((rule) => {
          return rule.tags.some((tag) => tags.includes(tag.toLowerCase()));
        });
        if (matchingRules.length === 0) {
          return null;
        }
        const rule = matchingRules.reduce((best, current) =>
          current.seedLimitSeconds < best.seedLimitSeconds ? current : best
        );
        const baseMs = addedOnMs || nowTick;
        const elapsedSeconds = Math.max(0, (nowTick - baseMs) / 1000);
        const remainingSeconds = rule.seedLimitSeconds - elapsedSeconds;
        return {
          torrent,
          rule,
          remainingSeconds,
        };
      })
      .filter(Boolean) as Array<{
      torrent: typeof torrents[number];
      rule: typeof timerRules[number];
      remainingSeconds: number;
    }>;
  }, [timerRules, torrents, nowTick]);

  const sortedMatchingTorrents = useMemo(() => {
    const direction = sortDirection === "asc" ? 1 : -1;
    const withFallback = (value: number | string | undefined, fallback: number | string) =>
      value === undefined || value === null || value === "" ? fallback : value;

    return [...matchingTorrents].sort((a, b) => {
      switch (sortKey) {
        case "name":
          return (
            String(withFallback(a.torrent.name, ""))
              .localeCompare(String(withFallback(b.torrent.name, "")), "tr") *
            direction
          );
        case "size":
          return (
            (Number(withFallback(a.torrent.size, 0)) -
              Number(withFallback(b.torrent.size, 0))) *
            direction
          );
        case "tracker":
          return (
            trackerLabel(a.torrent.tracker)
              .localeCompare(trackerLabel(b.torrent.tracker), "tr") * direction
          );
        case "addedOn":
          return (
            (Number(withFallback(a.torrent.added_on, 0)) -
              Number(withFallback(b.torrent.added_on, 0))) *
            direction
          );
        case "countdown":
        default:
          return (
            (Number(withFallback(a.remainingSeconds, 0)) -
              Number(withFallback(b.remainingSeconds, 0))) *
            direction
          );
      }
    });
  }, [matchingTorrents, sortDirection, sortKey]);

  useEffect(() => {
    let active = true;
    const load = async () => {
      try {
        const [rulesRes, logsRes, summaryRes] = await Promise.all([
          api.get("/api/timer/rules"),
          api.get("/api/timer/logs"),
          api.get("/api/timer/summary"),
        ]);
        if (!active) return;
        setTimerRules(rulesRes.data ?? []);
        setTimerLogs((logsRes.data ?? []).reverse());
        if (summaryRes.data) {
          setTimerSummary(summaryRes.data);
        }
      } catch (err) {
        if (active) {
          pushAlert({
            title: "Timer verileri alınamadı",
            description: "Bağlantıyı kontrol edip tekrar deneyin.",
            variant: "error",
          });
        }
      }
    };
    load();
    return () => {
      active = false;
    };
  }, [setTimerLogs, setTimerRules, setTimerSummary]);

  useEffect(() => {
    const interval = setInterval(() => setNowTick(Date.now()), 1000);
    return () => clearInterval(interval);
  }, []);

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

  const handleSaveRule = async () => {
    const unit = unitOptions.find((item) => item.value === seedUnit);
    if (!unit) return;
    if (selectedTags.length === 0) {
      pushAlert({
        title: "Etiket seçilmedi",
        description: "En az bir etiket seçmelisiniz.",
        variant: "warn",
      });
      return;
    }
    if (!Number.isFinite(seedValue) || seedValue <= 0) {
      pushAlert({
        title: "Seed süresi geçersiz",
        description: "Seed süresi 0’dan büyük olmalı.",
        variant: "warn",
      });
      return;
    }
    const seedLimitSeconds = Math.round(seedValue * unit.seconds);
    setBusy(true);
    try {
      const response = await api.post("/api/timer/rules", {
        tags: selectedTags,
        seedLimitSeconds,
        deleteFiles,
      });
      setTimerRules([response.data, ...timerRules]);
      setSelectedTags([]);
      setDeleteFiles(true);
      pushAlert({
        title: "Kural kaydedildi",
        description: "Timer kuralı aktif edildi.",
        variant: "success",
      });
    } catch (err) {
      pushAlert({
        title: "Kural kaydedilemedi",
        description: "Lütfen daha sonra tekrar deneyin.",
        variant: "error",
      });
    } finally {
      setBusy(false);
    }
  };

  const handleDeleteRule = async (ruleId: string) => {
    try {
      await api.delete(`/api/timer/rules/${ruleId}`);
      setTimerRules(timerRules.filter((rule) => rule.id !== ruleId));
      pushAlert({
        title: "Kural silindi",
        description: "Timer kuralı kaldırıldı.",
        variant: "success",
      });
    } catch (err) {
      pushAlert({
        title: "Kural silinemedi",
        description: "Lütfen daha sonra tekrar deneyin.",
        variant: "error",
      });
    }
  };

  const summary = timerSummary ?? {
    totalDeleted: 0,
    totalSeededSeconds: 0,
    totalUploadedBytes: 0,
    updatedAt: "",
  };

  return (
    <div className="grid w-full grid-cols-1 gap-6 lg:grid-cols-[1.3fr_0.7fr]">
      <div className="min-w-0 space-y-6">
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <FontAwesomeIcon icon={faHourglassHalf} className="text-slate-400" />
              Zamanlayıcı Torrentleri
            </CardTitle>
            <div className="flex items-center gap-2 text-xs font-semibold text-slate-500">
              <span>Sıralama</span>
              <Select
                value={sortKey}
                onValueChange={(value) => {
                  if (value !== sortKey) {
                    setSortKey(value as typeof sortKey);
                    setSortDirection("asc");
                  }
                }}
              >
                <SelectTrigger className="h-9 w-[180px] flex-shrink-0 text-xs">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {sortOptions.map((option) => (
                    <SelectItem
                      key={option.value}
                      value={option.value}
                      onPointerDown={() => {
                        if (option.value === sortKey) {
                          setSortDirection((current) =>
                            current === "asc" ? "desc" : "asc"
                          );
                        }
                      }}
                      onKeyDown={(event) => {
                        if (option.value !== sortKey) return;
                        if (event.key === "Enter" || event.key === " ") {
                          setSortDirection((current) =>
                            current === "asc" ? "desc" : "asc"
                          );
                        }
                      }}
                    >
                      {option.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </CardHeader>
          <CardContent className="space-y-4">
            {sortedMatchingTorrents.length === 0 ? (
              <div className="text-sm text-slate-500">
                Bu kurallara bağlı aktif torrent bulunamadı.
              </div>
            ) : (
              <div className="space-y-3">
                {sortedMatchingTorrents.map(({ torrent, rule, remainingSeconds }) => (
                  <div
                    key={torrent.hash}
                    className="rounded-lg border border-slate-200 bg-white px-3 py-2"
                  >
                    <div className="flex items-start justify-between gap-3">
                      <div className="min-w-0 flex-1">
                        <div
                          className="truncate text-sm font-semibold text-slate-900"
                          title={torrent.name}
                        >
                          {torrent.name}
                        </div>
                        <div className="truncate text-xs text-slate-500">
                          {formatBytes(torrent.size)} • {trackerLabel(torrent.tracker)}
                        </div>
                      </div>
                      <div className="w-24 flex-shrink-0 text-right text-xs text-slate-600">
                        <div className="font-semibold text-slate-900">
                          {formatCountdown(remainingSeconds)}
                        </div>
                        <div>Kural: {formatDuration(rule.seedLimitSeconds)}</div>
                      </div>
                    </div>
                    <div className="mt-2 flex items-center gap-1 text-xs text-slate-600">
                      <div className="truncate">
                        Hash: {torrent.hash.slice(0, 12)}...
                      </div>
                      <div className="truncate">
                        Etiket:{" "}
                        {(torrent.tags || torrent.category || "-")
                          .split(",")
                          .map((tag) => tag.trim())
                          .filter(Boolean)
                          .join(", ") || "-"}
                      </div>
                      <div className="truncate">
                        Added: {formatAddedOn(torrent.added_on)}
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </CardContent>
        </Card>
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <FontAwesomeIcon icon={faTrash} className="text-slate-400" />
              Silinen Torrent Logları
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-3 overflow-hidden">
            {timerLogs.length === 0 ? (
              <div className="text-sm text-slate-500">Henüz log yok.</div>
            ) : (
              <div className="overflow-hidden" style={{ height: 560 }}>
                <ScrollArea className="h-full w-full" type="always">
                  <div className="space-y-3 pr-3">
                    {timerLogs.map((log) => (
                      <div
                        key={log.id}
                        className="rounded-lg border border-slate-200 bg-white px-3 py-2"
                      >
                        <div className="flex items-start justify-between gap-3">
                          <div>
                            <div className="text-sm font-semibold text-slate-900">
                              {log.name}
                            </div>
                            <div className="text-xs text-slate-500">
                              {formatBytes(log.sizeBytes)} •{" "}
                              {trackerLabel(log.tracker)}
                            </div>
                          </div>
                          <div className="text-xs text-slate-400">
                            {new Date(log.deletedAt).toLocaleString()}
                          </div>
                        </div>
                        <div className="mt-2 flex flex-wrap gap-2 text-xs text-slate-600">
                          <span>Seed: {formatDuration(log.seedingTimeSeconds)}</span>
                          <span>Upload: {formatBytes(log.uploadedBytes)}</span>
                          {log.tags?.length ? (
                            <span>Tags: {log.tags.join(", ")}</span>
                          ) : null}
                        </div>
                      </div>
                    ))}
                  </div>
                </ScrollArea>
              </div>
            )}
          </CardContent>
        </Card>
      </div>

      <div className="min-w-0 space-y-6">
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <FontAwesomeIcon icon={faPlus} className="text-slate-400" />
              Timer Kuralı Oluştur
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <div>
              <div className="flex items-center gap-2 text-xs font-semibold text-slate-500">
                <FontAwesomeIcon icon={faTags} className="text-slate-400" />
                Etiketler
              </div>
              <div className="mt-2 flex flex-wrap gap-2">
                {tagOptions.length === 0 ? (
                  <div className="text-sm text-slate-500">
                    Henüz etiket bulunamadı.
                  </div>
                ) : (
                  tagOptions.map((tag) => (
                    <button
                      key={tag}
                      type="button"
                      onClick={() => toggleTag(tag)}
                      className={`rounded-full border px-3 py-1 text-xs font-semibold ${
                        selectedTags.includes(tag)
                          ? "border-slate-900 bg-slate-900 text-white"
                          : "border-slate-200 bg-white text-slate-600 hover:border-slate-300"
                      }`}
                    >
                      {tag}
                    </button>
                  ))
                )}
              </div>
            </div>
            <div>
              <div className="flex items-center gap-2 text-xs font-semibold text-slate-500">
                <FontAwesomeIcon icon={faClock} className="text-slate-400" />
                Seed Süresi
              </div>
              <div className="mt-2 flex gap-2">
                <Input
                  type="number"
                  min={1}
                  value={seedValue}
                  onChange={(event) => setSeedValue(Number(event.target.value))}
                />
                <select
                  value={seedUnit}
                  onChange={(event) =>
                    setSeedUnit(event.target.value as typeof seedUnit)
                  }
                  className="h-10 rounded-md border border-slate-200 bg-white px-3 text-sm text-slate-700"
                >
                  {unitOptions.map((unit) => (
                    <option key={unit.value} value={unit.value}>
                      {unit.label}
                    </option>
                  ))}
                </select>
              </div>
            </div>
            <label className="flex items-start gap-2 text-sm text-slate-700">
              <input
                type="checkbox"
                checked={deleteFiles}
                onChange={(event) => setDeleteFiles(event.target.checked)}
                className="mt-1 h-4 w-4 rounded border-slate-300 text-slate-900"
              />
              <span>
                Dosyayı Disk'ten Kaldır
                <span className="block text-xs text-slate-500">
                  İşaretli değilse torrent sadece qBittorrent'tan kaldırılır, dosya disk üzerinde kalır.
                </span>
              </span>
            </label>
            <Button onClick={handleSaveRule} disabled={busy}>
              {busy ? "Kaydediliyor..." : "Kuralı Kaydet"}
            </Button>
            <div className="border-t border-slate-200 pt-3">
              <div className="mb-2 flex items-center gap-2 text-xs font-semibold text-slate-500">
                <FontAwesomeIcon icon={faClockRotateLeft} className="text-slate-400" />
                Eklenen Kurallar
              </div>
              {rulesForDisplay.length === 0 ? (
                <div className="text-sm text-slate-500">
                  Henüz kural yok.
                </div>
              ) : (
                <div className="space-y-2">
                  {rulesForDisplay.map((rule) => (
                    <div
                      key={rule.id}
                      className="flex items-center justify-between rounded-lg border border-slate-200 bg-slate-50 px-3 py-2 text-sm"
                    >
                      <div>
                        <div className="font-semibold text-slate-900">
                          {rule.tags.join(", ")}
                        </div>
                        <div className="text-xs text-slate-500">
                          Seed limiti: {formatDuration(rule.seedLimitSeconds)}
                          {" • "}
                          {rule.deleteFiles ?? true
                            ? "Silme: Disk + qBittorrent"
                            : "Silme: Sadece qBittorrent"}
                        </div>
                      </div>
                      <AlertDialog>
                        <AlertDialogTrigger asChild>
                          <Button
                            variant="ghost"
                            className="text-rose-600 hover:text-rose-700"
                          >
                            <FontAwesomeIcon icon={faTrash} className="mr-2" />
                            Sil
                          </Button>
                        </AlertDialogTrigger>
                        <AlertDialogContent>
                          <AlertDialogHeader>
                            <AlertDialogTitle>Kural silinsin mi?</AlertDialogTitle>
                            <AlertDialogDescription>
                              Bu kural kaldırılınca zamanlayıcı artık bu etiketleri izlemeyecek.
                            </AlertDialogDescription>
                          </AlertDialogHeader>
                          <AlertDialogFooter>
                            <AlertDialogCancel>İptal</AlertDialogCancel>
                            <AlertDialogAction onClick={() => handleDeleteRule(rule.id)}>
                              Sil
                            </AlertDialogAction>
                          </AlertDialogFooter>
                        </AlertDialogContent>
                      </AlertDialog>
                    </div>
                  ))}
                </div>
              )}
            </div>
          </CardContent>
        </Card>
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <FontAwesomeIcon icon={faChartBar} className="text-slate-400" />
              Timer Özeti
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-2 text-sm text-slate-700">
            <div className="flex items-center justify-between">
              <span>Silinen dosya sayısı</span>
              <span className="font-semibold text-slate-900">
                {summary.totalDeleted}
              </span>
            </div>
            <div className="flex items-center justify-between">
              <span>Toplam seed süresi</span>
              <span className="font-semibold text-slate-900">
                {formatDuration(summary.totalSeededSeconds)}
              </span>
            </div>
            <div className="flex items-center justify-between">
              <span>Toplam upload</span>
              <span className="font-semibold text-slate-900">
                {formatBytes(summary.totalUploadedBytes)}
              </span>
            </div>
          </CardContent>
        </Card>
      </div>
    </div>
  );
};
