"use client";

import * as React from "react";
import { toast } from "sonner";
import {
  Loader2,
  Save,
  Mail,
  FolderSearch,
  Server,
  Wifi,
  WifiOff,
  Check,
  RefreshCw,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { Badge } from "@/components/ui/badge";
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  CardDescription,
} from "@/components/ui/card";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

type SourceSettings = {
  emailImapHost: string;
  emailImapPort: number;
  emailImapUser: string;
  emailImapPass: string;
  emailImapTls: boolean;
  emailFolder: string;
  emailWatching: boolean;
  emailProcessed: string;
  emailProcessedFolder: string;
  ftpEnabled: boolean;
  ftpHost: string;
  ftpPort: number;
  ftpUser: string;
  ftpPass: string;
  ftpProtocol: "sftp" | "ftp" | "ftps";
  ftpIncomingDir: string;
  ftpProcessedDir: string;
  watchDir: string;
  watching: boolean;
};

export default function UploadSourcesPage() {
  const [settings, setSettings] = React.useState<SourceSettings>({
    emailImapHost: "",
    emailImapPort: 993,
    emailImapUser: "",
    emailImapPass: "",
    emailImapTls: true,
    emailFolder: "INBOX",
    emailWatching: false,
    emailProcessed: "mark_read",
    emailProcessedFolder: "Processed",
    ftpEnabled: false,
    ftpHost: "",
    ftpPort: 22,
    ftpUser: "",
    ftpPass: "",
    ftpProtocol: "sftp",
    ftpIncomingDir: "/incoming",
    ftpProcessedDir: "/processed",
    watchDir: "",
    watching: false,
  });
  const [loading, setLoading] = React.useState(true);
  const [saving, setSaving] = React.useState(false);
  const [emailTestStatus, setEmailTestStatus] = React.useState<
    "idle" | "testing" | "success" | "error"
  >("idle");
  const [ftpTestStatus, setFtpTestStatus] = React.useState<
    "idle" | "testing" | "success" | "error"
  >("idle");
  const [scanning, setScanning] = React.useState(false);

  React.useEffect(() => {
    fetch("/api/settings")
      .then((r) => r.json())
      .then((data) => {
        setSettings({
          emailImapHost: data.emailImapHost || "",
          emailImapPort: data.emailImapPort || 993,
          emailImapUser: data.emailImapUser || "",
          emailImapPass: data.emailImapPass || "",
          emailImapTls: data.emailImapTls ?? true,
          emailFolder: data.emailFolder || "INBOX",
          emailWatching: data.emailWatching || false,
          emailProcessed: data.emailProcessed || "mark_read",
          emailProcessedFolder: data.emailProcessedFolder || "Processed",
          ftpEnabled: data.ftpEnabled || false,
          ftpHost: data.ftpHost || "",
          ftpPort: data.ftpPort || 22,
          ftpUser: data.ftpUser || "",
          ftpPass: data.ftpPass || "",
          ftpProtocol: data.ftpProtocol || "sftp",
          ftpIncomingDir: data.ftpIncomingDir || "/incoming",
          ftpProcessedDir: data.ftpProcessedDir || "/processed",
          watchDir: data.watchDir || "",
          watching: data.watching || false,
        });
        setLoading(false);
      })
      .catch(() => setLoading(false));
  }, []);

  const handleSave = async () => {
    setSaving(true);
    try {
      const payload = { ...settings } as Record<string, unknown>;
      if (payload.emailImapPass === "••••••••") delete payload.emailImapPass;
      if (payload.ftpPass === "••••••••") delete payload.ftpPass;

      const res = await fetch("/api/settings", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });
      if (!res.ok) throw new Error();
      toast.success("Upload source settings saved");
    } catch {
      toast.error("Failed to save settings");
    } finally {
      setSaving(false);
    }
  };

  const testEmail = async () => {
    setEmailTestStatus("testing");
    try {
      const res = await fetch("/api/email-watch/test", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          host: settings.emailImapHost,
          port: settings.emailImapPort,
          user: settings.emailImapUser,
          pass: settings.emailImapPass,
          tls: settings.emailImapTls,
        }),
      });
      const data = await res.json();
      setEmailTestStatus(res.ok ? "success" : "error");
      if (res.ok) toast.success(data.message || "Email connection successful");
      else toast.error(data.error || "Email connection failed");
    } catch {
      setEmailTestStatus("error");
      toast.error("Email test failed");
    }
  };

  const scanNow = async () => {
    setScanning(true);
    try {
      const res = await fetch("/api/email-watch", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action: "scan" }),
      });
      if (res.ok) {
        const data = await res.json();
        toast.success(`Scanned ${data.processed || 0} emails`);
      } else {
        const data = await res.json().catch(() => ({}));
        toast.error(data.error || "Scan failed");
      }
    } catch {
      toast.error("Scan failed");
    } finally {
      setScanning(false);
    }
  };

  const testFtp = async () => {
    setFtpTestStatus("testing");
    try {
      const res = await fetch("/api/ftp-watch/test", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          host: settings.ftpHost,
          port: settings.ftpPort,
          user: settings.ftpUser,
          pass: settings.ftpPass,
          protocol: settings.ftpProtocol,
          incomingDir: settings.ftpIncomingDir,
        }),
      });
      const data = await res.json();
      setFtpTestStatus(res.ok && data.ok ? "success" : "error");
      if (res.ok && data.ok) {
        toast.success(`FTP connected — ${data.files ?? 0} file(s) found`);
      } else {
        toast.error(data.error || "FTP connection failed");
      }
    } catch {
      setFtpTestStatus("error");
      toast.error("FTP test failed");
    }
  };

  const toggleFolderWatch = async () => {
    const endpoint = settings.watching ? "/api/watch/stop" : "/api/watch/start";
    try {
      const res = await fetch(endpoint, { method: "POST" });
      if (res.ok) {
        setSettings((s) => ({ ...s, watching: !s.watching }));
        toast.success(
          settings.watching ? "Folder watch stopped" : "Folder watch started"
        );
      }
    } catch {
      toast.error("Failed to toggle folder watch");
    }
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center py-20">
        <Loader2 className="size-6 animate-spin text-muted-foreground" />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Email Inbox */}
      <Card className="glass-card">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <Mail className="size-4" />
            Email Inbox
          </CardTitle>
          <CardDescription>
            Auto-import response cards from an email inbox via IMAP.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid gap-4 sm:grid-cols-2">
            <div className="space-y-2">
              <Label>IMAP Host</Label>
              <Input
                value={settings.emailImapHost}
                onChange={(e) =>
                  setSettings((s) => ({ ...s, emailImapHost: e.target.value }))
                }
                placeholder="imap.gmail.com"
              />
            </div>
            <div className="space-y-2">
              <Label>Port</Label>
              <Input
                type="number"
                value={settings.emailImapPort}
                onChange={(e) =>
                  setSettings((s) => ({
                    ...s,
                    emailImapPort: parseInt(e.target.value) || 993,
                  }))
                }
              />
            </div>
            <div className="space-y-2">
              <Label>Username</Label>
              <Input
                value={settings.emailImapUser}
                onChange={(e) =>
                  setSettings((s) => ({ ...s, emailImapUser: e.target.value }))
                }
              />
            </div>
            <div className="space-y-2">
              <Label>Password</Label>
              <Input
                type="password"
                value={settings.emailImapPass}
                onChange={(e) =>
                  setSettings((s) => ({ ...s, emailImapPass: e.target.value }))
                }
              />
            </div>
          </div>

          <div className="flex items-center gap-4">
            <div className="flex items-center gap-2">
              <Switch
                checked={settings.emailImapTls}
                onCheckedChange={(v) =>
                  setSettings((s) => ({ ...s, emailImapTls: v }))
                }
              />
              <Label className="text-sm">Use TLS</Label>
            </div>
          </div>

          <div className="grid gap-4 sm:grid-cols-2">
            <div className="space-y-2">
              <Label>Folder</Label>
              <Input
                value={settings.emailFolder}
                onChange={(e) =>
                  setSettings((s) => ({ ...s, emailFolder: e.target.value }))
                }
              />
            </div>
            <div className="space-y-2">
              <Label>After Processing</Label>
              <Select
                value={settings.emailProcessed}
                onValueChange={(v) =>
                  v && setSettings((s) => ({ ...s, emailProcessed: v }))
                }
              >
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="mark_read">Mark as read</SelectItem>
                  <SelectItem value="move">Move to folder</SelectItem>
                  <SelectItem value="delete">Delete</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>

          <div className="flex items-center gap-2">
            <Button variant="outline" size="sm" onClick={testEmail}>
              {emailTestStatus === "testing" ? (
                <Loader2 className="mr-1.5 size-3.5 animate-spin" />
              ) : emailTestStatus === "success" ? (
                <Check className="mr-1.5 size-3.5 text-emerald-500" />
              ) : (
                <Mail className="mr-1.5 size-3.5" />
              )}
              Test Connection
            </Button>
            <Button variant="outline" size="sm" onClick={scanNow} disabled={scanning}>
              {scanning ? (
                <Loader2 className="mr-1.5 size-3.5 animate-spin" />
              ) : (
                <RefreshCw className="mr-1.5 size-3.5" />
              )}
              Scan Now
            </Button>
            <div className="flex items-center gap-2">
              <Switch
                checked={settings.emailWatching}
                onCheckedChange={(v) =>
                  setSettings((s) => ({ ...s, emailWatching: v }))
                }
              />
              <Label className="text-sm">Auto-watch</Label>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* FTP */}
      <Card className="glass-card">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <Server className="size-4" />
            SFTP / FTP Server
          </CardTitle>
          <CardDescription>
            Poll a remote server for new scanned files via SFTP, FTP, or FTPS.
            Files are downloaded, processed, then moved to a
            &ldquo;processed&rdquo; directory.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="flex items-center gap-4">
            <div className="flex items-center gap-2">
              <Switch
                checked={settings.ftpEnabled}
                onCheckedChange={(v) =>
                  setSettings((s) => ({ ...s, ftpEnabled: !!v }))
                }
              />
              <Label className="text-sm">Enable FTP watcher</Label>
            </div>
          </div>

          <div className="grid gap-4 sm:grid-cols-3">
            <div className="space-y-2">
              <Label>Protocol</Label>
              <Select
                value={settings.ftpProtocol}
                onValueChange={(v) => {
                  const proto = v as "sftp" | "ftp" | "ftps";
                  const defaultPort = proto === "sftp" ? 22 : 21;
                  setSettings((s) => ({
                    ...s,
                    ftpProtocol: proto,
                    ftpPort: defaultPort,
                  }));
                }}
              >
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="sftp">SFTP (SSH)</SelectItem>
                  <SelectItem value="ftp">FTP</SelectItem>
                  <SelectItem value="ftps">FTPS (TLS)</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label>Host</Label>
              <Input
                value={settings.ftpHost}
                onChange={(e) =>
                  setSettings((s) => ({ ...s, ftpHost: e.target.value }))
                }
                placeholder="ftp.example.com"
              />
            </div>
            <div className="space-y-2">
              <Label>Port</Label>
              <Input
                type="number"
                value={settings.ftpPort}
                onChange={(e) =>
                  setSettings((s) => ({
                    ...s,
                    ftpPort: parseInt(e.target.value) || 22,
                  }))
                }
              />
            </div>
          </div>

          <div className="grid gap-4 sm:grid-cols-2">
            <div className="space-y-2">
              <Label>Username</Label>
              <Input
                value={settings.ftpUser}
                onChange={(e) =>
                  setSettings((s) => ({ ...s, ftpUser: e.target.value }))
                }
              />
            </div>
            <div className="space-y-2">
              <Label>Password</Label>
              <Input
                type="password"
                value={settings.ftpPass}
                onChange={(e) =>
                  setSettings((s) => ({ ...s, ftpPass: e.target.value }))
                }
              />
            </div>
          </div>

          <div className="grid gap-4 sm:grid-cols-2">
            <div className="space-y-2">
              <Label>Incoming Directory</Label>
              <Input
                value={settings.ftpIncomingDir}
                onChange={(e) =>
                  setSettings((s) => ({ ...s, ftpIncomingDir: e.target.value }))
                }
                placeholder="/incoming"
              />
            </div>
            <div className="space-y-2">
              <Label>Processed Directory</Label>
              <Input
                value={settings.ftpProcessedDir}
                onChange={(e) =>
                  setSettings((s) => ({
                    ...s,
                    ftpProcessedDir: e.target.value,
                  }))
                }
                placeholder="/processed"
              />
            </div>
          </div>

          <div className="flex items-center gap-2">
            <Button
              variant="outline"
              size="sm"
              onClick={testFtp}
              disabled={!settings.ftpHost || !settings.ftpUser}
            >
              {ftpTestStatus === "testing" ? (
                <Loader2 className="mr-1.5 size-3.5 animate-spin" />
              ) : ftpTestStatus === "success" ? (
                <Check className="mr-1.5 size-3.5 text-emerald-500" />
              ) : (
                <Server className="mr-1.5 size-3.5" />
              )}
              Test Connection
            </Button>
          </div>
        </CardContent>
      </Card>

      {/* Folder Watch */}
      <Card className="glass-card">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-base">
            <FolderSearch className="size-4" />
            Folder Watch
          </CardTitle>
          <CardDescription>
            Monitor a local directory for new scanned files.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="space-y-2">
            <Label>Watch Directory</Label>
            <Input
              value={settings.watchDir}
              onChange={(e) =>
                setSettings((s) => ({ ...s, watchDir: e.target.value }))
              }
              placeholder="/mnt/scans"
            />
          </div>
          <div className="flex items-center gap-3">
            <Button
              variant="outline"
              size="sm"
              onClick={toggleFolderWatch}
            >
              {settings.watching ? (
                <>
                  <WifiOff className="mr-1.5 size-3.5" />
                  Stop Watching
                </>
              ) : (
                <>
                  <Wifi className="mr-1.5 size-3.5" />
                  Start Watching
                </>
              )}
            </Button>
            {settings.watching && (
              <Badge variant="outline" className="text-emerald-500">
                Active
              </Badge>
            )}
          </div>
        </CardContent>
      </Card>

      <div className="flex justify-end">
        <Button onClick={handleSave} disabled={saving}>
          {saving ? (
            <Loader2 className="mr-2 size-4 animate-spin" />
          ) : (
            <Save className="mr-2 size-4" />
          )}
          Save Changes
        </Button>
      </div>
    </div>
  );
}
