import React, { useEffect, useMemo, useState } from "react";
import { useAppStore } from "../../store/useAppStore";
import { Card, CardContent, CardHeader, CardTitle } from "../ui/Card";
import { Input } from "../ui/Input";
import { api } from "../../api/client";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "../ui/AlertDialog";
import { useUiStore } from "../../store/useUiStore";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faBolt, faCloudArrowDown, faCloudArrowUp, faHourglassHalf } from "@fortawesome/free-solid-svg-icons";

interface Profile {
  id: string;
  name: string;
  allowIp: string;
  delayMs: number;
  targetLoops: number;
}

const formatSpeed = (bytesPerSec: number) => {
  if (bytesPerSec <= 0) {
    return "00.0 KB/s";
  }
  const kb = bytesPerSec / 1024;
  if (kb >= 1024) {
    return `${(kb / 1024).toFixed(1)} MB/s`;
  }
  return `${kb.toFixed(1)} KB/s`;
};

const isUploadState = (state: string) => /upload|stalledup|forcedup|up$/i.test(state);

export const TorrentTable = () => {
  const torrents = useAppStore((s) => s.torrents);
  const selected = useAppStore((s) => s.selectedHash);
  const jobs = useAppStore((s) => s.jobs);
  const selectHash = useAppStore((s) => s.selectHash);
  const pushAlert = useUiStore((s) => s.pushAlert);
  const [query, setQuery] = useState("");
  const [profiles, setProfiles] = useState<Profile[]>([]);

  const loadProfiles = async () => {
    const response = await api.get("/api/profiles");
    setProfiles(response.data);
  };

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

  const renderState = (state: string) => {
    const value = state.toLowerCase();
    if (value.includes("forced")) {
      return <FontAwesomeIcon icon={faBolt} title="Forced" />;
    }
    if (value.includes("stalled")) {
      return <FontAwesomeIcon icon={faHourglassHalf} title="Stalled" />;
    }
    if (value.includes("downloading") || value.includes("metadl")) {
      return <FontAwesomeIcon icon={faCloudArrowDown} title="Downloading" />;
    }
    if (value.includes("uploading") || value.includes("up")) {
      return <FontAwesomeIcon icon={faCloudArrowUp} title="Uploading" />;
    }
    return <span className="uppercase text-slate-400">{state}</span>;
  };

  const getProfileName = (hash: string) => {
    const hashKey = hash.toLowerCase();
    const related = jobs.filter((j) => j.torrentHash?.toLowerCase() === hashKey);
    if (related.length === 0) return null;
    const active = related.find((j) => j.status === "RUNNING" || j.status === "WAITING_DELAY");
    const latest = related.reduce((current, next) => {
      const currentAt = Date.parse(current.updatedAt ?? current.createdAt ?? "");
      const nextAt = Date.parse(next.updatedAt ?? next.createdAt ?? "");
      if (Number.isFinite(nextAt) && Number.isFinite(currentAt)) {
        return nextAt >= currentAt ? next : current;
      }
      if (Number.isFinite(nextAt)) return next;
      return current;
    }, related[0]);
    const candidate = active ?? latest;
    if (candidate.profileId) {
      const profileById = profiles.find((p) => p.id === candidate.profileId);
      if (profileById?.name) {
        return profileById.name;
      }
    }
    if (candidate.profileName) {
      return candidate.profileName;
    }
    const fallback = profiles.find(
      (profile) =>
        profile.allowIp === candidate.allowIp &&
        profile.delayMs === candidate.delayMs &&
        profile.targetLoops === candidate.targetLoops
    );
    return fallback?.name ?? null;
  };

  const filtered = useMemo(() => {
    return torrents
      .filter((torrent) =>
        torrent.name.toLowerCase().includes(query.toLowerCase())
      )
      .sort((a, b) => (b.added_on ?? 0) - (a.added_on ?? 0));
  }, [torrents, query]);

  const deleteTorrent = async (hash: string) => {
    try {
      await api.delete(`/api/qbit/torrent/${hash}`);
      pushAlert({
        title: "Torrent silindi",
        description: "Torrent ve dosyalar diskten kaldırıldı.",
        variant: "success",
      });
    } catch (error) {
      pushAlert({
        title: "Silme başarısız",
        description: "Torrent silinemedi. Sunucu loglarını kontrol edin.",
        variant: "error",
      });
    }
  };

  const uploadTorrent = async (hash: string, file: File) => {
    const form = new FormData();
    form.append("file", file);
    form.append("hash", hash);
    try {
      const response = await api.post("/api/torrent/archive/upload", form, {
        headers: { "Content-Type": "multipart/form-data" },
      });
      if (response.data?.added) {
        pushAlert({
          title: "Yükleme başarılı",
          description: "Torrent qBittorrent'a eklendi.",
          variant: "success",
        });
      } else {
        pushAlert({
          title: "Yükleme yapıldı",
          description: "Torrent arşive alındı, qBittorrent'a eklenemedi.",
          variant: "warn",
        });
      }
    } catch (error: any) {
      const apiError = error?.response?.data?.error;
      pushAlert({
        title: "Yükleme başarısız",
        description: apiError || "Sunucu loglarını kontrol edin.",
        variant: "error",
      });
    }
  };

  return (
    <Card className="flex h-full flex-col">
      <CardHeader className="flex items-center gap-3">
        <CardTitle>Torrents</CardTitle>
        <Input
          placeholder="Search"
          value={query}
          onChange={(event) => setQuery(event.target.value)}
          className="ml-auto w-28"
        />
      </CardHeader>
      <CardContent className="flex-1">
        <div className="h-full overflow-auto space-y-2">
          {filtered.map((torrent) => (
            <div
              key={torrent.hash}
              className={`group flex min-w-0 items-start justify-between rounded-lg border px-3 py-2 text-left text-sm transition ${
                selected === torrent.hash
                  ? "is-selected border-ink bg-slate-900 text-white"
                  : "border-slate-200 bg-white hover:border-slate-300"
              }`}
            >
              <div
                className="min-w-0 flex-1 cursor-pointer"
                onClick={() => selectHash(torrent.hash)}
              >
                <div className="min-w-0 truncate font-semibold" title={torrent.name}>
                  {torrent.name}
                </div>
                <div className="mt-2 flex items-center gap-1 text-xs">
                  <div className="h-2 w-28 shrink-0 rounded-full bg-slate-200">
                    <div
                      className="h-2 rounded-full bg-mint"
                      style={{ width: `${Math.round(torrent.progress * 100)}%` }}
                    />
                  </div>
                  <span className="w-8 text-left tabular-nums">{Math.round(torrent.progress * 100)}%</span>
                  <span className="w-16 text-left tabular-nums">{formatSpeed(isUploadState(torrent.state) ? (torrent.upspeed ?? 0) : torrent.dlspeed)}</span>
                  <span className="flex items-center gap-2 text-slate-500 group-[.is-selected]:text-white whitespace-nowrap">
                    {renderState(torrent.state)}
                    {getProfileName(torrent.hash) && (
                      <span className="text-xs text-slate-500 group-[.is-selected]:text-white">{getProfileName(torrent.hash)}</span>
                    )}
                  </span>
                </div>
              </div>
              <div className="ml-3 flex items-center gap-2">
                <label
                  className="cursor-pointer rounded-md p-2 text-slate-500 transition hover:bg-slate-100 hover:text-slate-900 group-[.is-selected]:text-white group-[.is-selected]:hover:bg-white/10"
                  title="Torrent yükle"
                >
                  <input
                    type="file"
                    accept=".torrent"
                    className="hidden"
                    onChange={async (event) => {
                      const file = event.target.files?.[0];
                      if (file) {
                        await uploadTorrent(torrent.hash, file);
                      }
                      event.target.value = "";
                    }}
                  />
                  <svg
                    xmlns="http://www.w3.org/2000/svg"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    className="h-4 w-4"
                  >
                    <path d="M12 3v12" />
                    <path d="M8 7l4-4 4 4" />
                    <path d="M4 15v4h16v-4" />
                  </svg>
                </label>
                <AlertDialog>
                <AlertDialogTrigger asChild>
                  <button
                    className="rounded-md p-2 text-slate-500 transition hover:bg-slate-100 hover:text-slate-900 group-[.is-selected]:text-white group-[.is-selected]:hover:bg-white/10"
                    title="Sil"
                    onClick={(event) => event.stopPropagation()}
                    type="button"
                  >
                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="2"
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      className="h-4 w-4"
                    >
                      <path d="M3 6h18" />
                      <path d="M8 6V4h8v2" />
                      <path d="M19 6l-1 14H6L5 6" />
                      <path d="M10 11v6" />
                      <path d="M14 11v6" />
                    </svg>
                  </button>
                </AlertDialogTrigger>
                <AlertDialogContent onClick={(event) => event.stopPropagation()}>
                  <AlertDialogHeader>
                    <AlertDialogTitle>Torrent silinsin mi?</AlertDialogTitle>
                    <AlertDialogDescription>
                      Bu işlem torrent ve indirilmiş dosyaları kalıcı olarak siler.
                    </AlertDialogDescription>
                  </AlertDialogHeader>
                  <AlertDialogFooter>
                    <AlertDialogCancel>İptal</AlertDialogCancel>
                    <AlertDialogAction onClick={() => deleteTorrent(torrent.hash)}>
                      Sil
                    </AlertDialogAction>
                  </AlertDialogFooter>
                </AlertDialogContent>
              </AlertDialog>
              </div>
            </div>
          ))}
        </div>
      </CardContent>
    </Card>
  );
};
