// @File: src/pages/ClientCpanel.tsx
// @Desc: Client-area cPanel dashboard — shows provisioned hosting accounts,
//        resource usage, single-sign-on to cPanel, and quick actions for
//        email, FTP, MySQL and subdomains.
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Alert, AlertDescription } from "@/components/ui/alert";
import {
  Tabs, TabsContent, TabsList, TabsTrigger,
} from "@/components/ui/tabs";
import {
  cpanelClient,
  type CpanelAccount,
  type CpanelAccountDetail,
  type SimpleItem,
} from "@/lib/cpanelApi";

type Section = "emails" | "ftp" | "databases" | "subdomains" | "ssl" | "backups";

export default function ClientCpanel() {
  const [accounts, setAccounts] = useState<CpanelAccount[]>([]);
  const [selected, setSelected] = useState<CpanelAccountDetail | null>(null);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState<string | null>(null);

  const reloadList = async () => {
    try {
      const list = await cpanelClient.listMyAccounts();
      setAccounts(list);
      if (list.length && !selected) {
        const detail = await cpanelClient.getAccount(list[0].id);
        setSelected(detail);
      }
    } catch (e) {
      setErr(e instanceof Error ? e.message : "Failed to load");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    void reloadList();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const reloadDetail = async (id: number) => {
    try {
      setSelected(await cpanelClient.getAccount(id));
    } catch (e) {
      setErr(e instanceof Error ? e.message : "Failed to load account");
    }
  };

  const openSso = async (id: number) => {
    try {
      const res = await cpanelClient.sso(id);
      window.open(res.url, "_blank", "noopener,noreferrer");
    } catch (e) {
      alert(e instanceof Error ? e.message : "Could not open cPanel");
    }
  };

  const syncUsage = async (id: number) => {
    try {
      await cpanelClient.syncUsage(id);
      await reloadDetail(id);
    } catch (e) {
      alert(e instanceof Error ? e.message : "Sync failed");
    }
  };

  return (
    <div className="mx-auto max-w-6xl p-6 space-y-6">
      <div>
        <h1 className="text-2xl font-bold">My Hosting Accounts</h1>
        <p className="text-sm text-muted-foreground">Manage your cPanel accounts provisioned through DoItEasy.</p>
      </div>

      {err && <Alert variant="destructive"><AlertDescription>{err}</AlertDescription></Alert>}

      {loading ? (
        <p className="text-sm text-muted-foreground">Loading…</p>
      ) : accounts.length === 0 ? (
        <Card>
          <CardContent className="py-10 text-center">
            <p className="text-sm text-muted-foreground">
              You don't have any hosting accounts yet. Purchase a plan to get started.
            </p>
          </CardContent>
        </Card>
      ) : (
        <div className="grid gap-4 md:grid-cols-[280px,1fr]">
          <div className="space-y-2">
            {accounts.map((a) => (
              <button
                key={a.id}
                onClick={() => reloadDetail(a.id)}
                className={`w-full text-left rounded border p-3 hover:bg-muted ${
                  selected?.id === a.id ? "bg-muted" : ""
                }`}
              >
                <div className="font-medium">{a.main_domain}</div>
                <div className="text-xs text-muted-foreground font-mono">{a.cpanel_username}</div>
                <Badge
                  className="mt-1"
                  variant={a.status === "active" ? "default" : a.status === "suspended" ? "secondary" : "outline"}
                >
                  {a.status}
                </Badge>
              </button>
            ))}
          </div>

          {selected && <AccountDetailPanel account={selected} onSso={openSso} onSync={syncUsage} />}
        </div>
      )}
    </div>
  );
}

function AccountDetailPanel({
  account,
  onSso,
  onSync,
}: {
  account: CpanelAccountDetail;
  onSso: (id: number) => void;
  onSync: (id: number) => void;
}) {
  const usage = account.usage;
  return (
    <Card>
      <CardHeader>
        <div className="flex flex-wrap items-start justify-between gap-3">
          <div>
            <CardTitle>{account.main_domain}</CardTitle>
            <CardDescription>
              cPanel user <span className="font-mono">{account.cpanel_username}</span>
              {account.package_name && <> · Plan <b>{account.package_name}</b></>}
              {account.server_hostname && <> · Server <span className="font-mono">{account.server_hostname}</span></>}
            </CardDescription>
          </div>
          <div className="flex gap-2">
            <Button variant="outline" onClick={() => onSync(account.id)}>Refresh usage</Button>
            <Button onClick={() => onSso(account.id)} disabled={account.status !== "active"}>
              Login to cPanel
            </Button>
          </div>
        </div>
      </CardHeader>
      <CardContent className="space-y-4">
        {account.status !== "active" && (
          <Alert>
            <AlertDescription>
              This account is currently <b>{account.status}</b>.
              {account.suspend_reason && <> Reason: {account.suspend_reason}.</>}
            </AlertDescription>
          </Alert>
        )}

        <div className="grid gap-3 md:grid-cols-4">
          <Metric label="Disk used" value={`${usage?.disk_used_mb ?? "—"} MB`} hint={usage?.disk_limit_mb ? `of ${usage.disk_limit_mb} MB` : undefined} />
          <Metric label="Email accounts" value={usage?.email_accounts ?? "—"} />
          <Metric label="Databases" value={usage?.databases ?? "—"} />
          <Metric label="SSL" value={usage?.ssl_status ?? "—"} />
        </div>

        <Tabs defaultValue="emails">
          <TabsList>
            <TabsTrigger value="emails">Email</TabsTrigger>
            <TabsTrigger value="ftp">FTP</TabsTrigger>
            <TabsTrigger value="databases">MySQL</TabsTrigger>
            <TabsTrigger value="subdomains">Subdomains</TabsTrigger>
            <TabsTrigger value="ssl">SSL</TabsTrigger>
            <TabsTrigger value="backups">Backups</TabsTrigger>
          </TabsList>
          {(["emails", "ftp", "databases", "subdomains", "ssl", "backups"] as Section[]).map((key) => (
            <TabsContent key={key} value={key}>
              <SectionPanel section={key} accountId={account.id} domain={account.main_domain} />
            </TabsContent>
          ))}
        </Tabs>
      </CardContent>
    </Card>
  );
}

function Metric({ label, value, hint }: { label: string; value: React.ReactNode; hint?: string }) {
  return (
    <div className="rounded border p-3">
      <div className="text-xs text-muted-foreground">{label}</div>
      <div className="text-xl font-semibold">{value}</div>
      {hint && <div className="text-xs text-muted-foreground mt-1">{hint}</div>}
    </div>
  );
}

function SectionPanel({
  section,
  accountId,
  domain,
}: {
  section: Section;
  accountId: number;
  domain: string;
}) {
  const [items, setItems] = useState<SimpleItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  // form state varies by section
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [username, setUsername] = useState("");
  const [dbName, setDbName] = useState("");
  const [subdomain, setSubdomain] = useState("");

  const load = async () => {
    setLoading(true);
    try {
      let data: SimpleItem[] = [];
      if (section === "emails") data = await cpanelClient.listEmails(accountId);
      else if (section === "ftp") data = await cpanelClient.listFtp(accountId);
      else if (section === "databases") data = await cpanelClient.listDatabases(accountId);
      else if (section === "subdomains") data = await cpanelClient.listSubdomains(accountId);
      else if (section === "ssl") data = await cpanelClient.listSsl(accountId);
      else if (section === "backups") data = await cpanelClient.listBackups(accountId);
      setItems(data);
      setErr(null);
    } catch (e) {
      setErr(e instanceof Error ? e.message : "Failed to load");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    void load();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [section, accountId]);

  const handleCreate = async () => {
    setBusy(true);
    try {
      if (section === "emails") {
        await cpanelClient.createEmail(accountId, { email, password, quota_mb: 250 });
        setEmail(""); setPassword("");
      } else if (section === "ftp") {
        await cpanelClient.createFtp(accountId, { username, password, quota_mb: 0 });
        setUsername(""); setPassword("");
      } else if (section === "databases") {
        await cpanelClient.createDatabase(accountId, dbName);
        setDbName("");
      } else if (section === "subdomains") {
        await cpanelClient.createSubdomain(accountId, { subdomain, parent_domain: domain });
        setSubdomain("");
      }
      await load();
    } catch (e) {
      alert(e instanceof Error ? e.message : "Create failed");
    } finally {
      setBusy(false);
    }
  };

  const handleDelete = async (name: string) => {
    if (!confirm(`Delete '${name}'?`)) return;
    try {
      if (section === "emails") await cpanelClient.deleteEmail(accountId, name);
      else if (section === "ftp") await cpanelClient.deleteFtp(accountId, name);
      else if (section === "databases") await cpanelClient.deleteDatabase(accountId, name);
      else return;
      await load();
    } catch (e) {
      alert(e instanceof Error ? e.message : "Delete failed");
    }
  };

  return (
    <div className="space-y-3 pt-3">
      {err && <Alert variant="destructive"><AlertDescription>{err}</AlertDescription></Alert>}

      {(section === "emails" || section === "ftp" || section === "databases" || section === "subdomains") && (
        <div className="grid gap-2 md:grid-cols-[1fr,1fr,auto] items-end">
          {section === "emails" && (
            <>
              <div>
                <Label>Email address</Label>
                <Input value={email} onChange={(e) => setEmail(e.target.value)} placeholder={`user@${domain}`} />
              </div>
              <div>
                <Label>Password</Label>
                <Input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
              </div>
            </>
          )}
          {section === "ftp" && (
            <>
              <div>
                <Label>FTP username</Label>
                <Input value={username} onChange={(e) => setUsername(e.target.value)} />
              </div>
              <div>
                <Label>Password</Label>
                <Input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
              </div>
            </>
          )}
          {section === "databases" && (
            <div className="md:col-span-2">
              <Label>Database name</Label>
              <Input value={dbName} onChange={(e) => setDbName(e.target.value)} />
            </div>
          )}
          {section === "subdomains" && (
            <div className="md:col-span-2">
              <Label>Subdomain prefix</Label>
              <Input value={subdomain} onChange={(e) => setSubdomain(e.target.value)} placeholder={`shop.${domain}`} />
            </div>
          )}
          <Button onClick={handleCreate} disabled={busy}>{busy ? "Creating…" : "Create"}</Button>
        </div>
      )}

      <div className="rounded border">
        {loading ? (
          <div className="p-3 text-sm text-muted-foreground">Loading…</div>
        ) : items.length === 0 ? (
          <div className="p-3 text-sm text-muted-foreground">Nothing here yet.</div>
        ) : (
          <ul className="divide-y">
            {items.map((it) => (
              <li key={it.name} className="flex items-center justify-between px-3 py-2 text-sm">
                <span className="font-mono">{it.name}</span>
                {(section === "emails" || section === "ftp" || section === "databases") && (
                  <Button size="sm" variant="ghost" onClick={() => handleDelete(it.name)}>Delete</Button>
                )}
              </li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}