"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { Loader2, Save } from "lucide-react";
import { toast } from "sonner";
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 {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { ConfirmDialog } from "@/components/admin/ui/confirm-dialog";
import { authClient, signOut } from "@/lib/auth/auth-client";
import { VOICE_CATALOG } from "@/lib/ai/voices";
import { LANGUAGES } from "@/lib/episodes/options";
import { savePreferencesAction, deleteAccountAction } from "@/app/(app)/settings/actions";

const NO_VOICE = "__none__";

interface Preferences {
  defaultVoiceId: string | null;
  defaultLanguage: string;
  emailOnEpisodeReady: boolean;
  productEmails: boolean;
}

export function SettingsClient({
  name,
  email,
  preferences,
}: {
  name: string;
  email: string;
  preferences: Preferences;
}) {
  const router = useRouter();
  const [displayName, setDisplayName] = useState(name);
  const [savingProfile, setSavingProfile] = useState(false);
  const [savingPw, setSavingPw] = useState(false);

  // Defaults
  const [voiceId, setVoiceId] = useState(preferences.defaultVoiceId ?? NO_VOICE);
  const [language, setLanguage] = useState(preferences.defaultLanguage);
  const [savingDefaults, setSavingDefaults] = useState(false);

  // Notifications
  const [emailOnReady, setEmailOnReady] = useState(preferences.emailOnEpisodeReady);
  const [productEmails, setProductEmails] = useState(preferences.productEmails);
  const [savingNotif, setSavingNotif] = useState(false);

  // Danger zone
  const [confirmEmail, setConfirmEmail] = useState("");

  async function saveProfile(e: React.FormEvent) {
    e.preventDefault();
    setSavingProfile(true);
    const { error } = await authClient.updateUser({ name: displayName });
    setSavingProfile(false);
    if (error) toast.error(error.message ?? "Could not update");
    else {
      toast.success("Profile updated");
      router.refresh();
    }
  }

  async function changePassword(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const form = new FormData(e.currentTarget);
    setSavingPw(true);
    const { error } = await authClient.changePassword({
      currentPassword: String(form.get("current")),
      newPassword: String(form.get("new")),
      revokeOtherSessions: true,
    });
    setSavingPw(false);
    if (error) toast.error(error.message ?? "Could not change password");
    else {
      toast.success("Password changed");
      e.currentTarget.reset();
    }
  }

  async function saveDefaults() {
    setSavingDefaults(true);
    const res = await savePreferencesAction({
      defaultVoiceId: voiceId === NO_VOICE ? null : voiceId,
      defaultLanguage: language,
    });
    setSavingDefaults(false);
    if (res.ok) toast.success("Defaults saved");
    else toast.error(res.error ?? "Could not save");
  }

  async function saveNotifications(next: Partial<Preferences>) {
    const emailVal = next.emailOnEpisodeReady ?? emailOnReady;
    const productVal = next.productEmails ?? productEmails;
    setEmailOnReady(emailVal);
    setProductEmails(productVal);
    setSavingNotif(true);
    const res = await savePreferencesAction({
      emailOnEpisodeReady: emailVal,
      productEmails: productVal,
    });
    setSavingNotif(false);
    if (!res.ok) {
      toast.error(res.error ?? "Could not save");
      // Revert optimistic state.
      setEmailOnReady(preferences.emailOnEpisodeReady);
      setProductEmails(preferences.productEmails);
    } else {
      toast.success("Notification preferences saved");
    }
  }

  return (
    <div className="max-w-xl space-y-6">
      <Card>
        <CardHeader>
          <CardTitle>Profile</CardTitle>
          <CardDescription>Update your name and see your email.</CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={saveProfile} className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="name">Name</Label>
              <Input id="name" value={displayName} onChange={(e) => setDisplayName(e.target.value)} />
            </div>
            <div className="space-y-2">
              <Label>Email</Label>
              <Input value={email} disabled />
            </div>
            <Button type="submit" disabled={savingProfile}>
              {savingProfile && <Loader2 className="h-4 w-4 animate-spin" />}
              Save profile
            </Button>
          </form>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>Password</CardTitle>
          <CardDescription>Change your account password.</CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={changePassword} className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="current">Current password</Label>
              <Input id="current" name="current" type="password" required />
            </div>
            <div className="space-y-2">
              <Label htmlFor="new">New password</Label>
              <Input id="new" name="new" type="password" minLength={8} required />
            </div>
            <Button type="submit" disabled={savingPw}>
              {savingPw && <Loader2 className="h-4 w-4 animate-spin" />}
              Change password
            </Button>
          </form>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>Defaults</CardTitle>
          <CardDescription>
            Pre-select a voice and language when creating new episodes.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="default-voice">Default host voice</Label>
            <Select value={voiceId} onValueChange={setVoiceId}>
              <SelectTrigger id="default-voice">
                <SelectValue placeholder="Choose a voice" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value={NO_VOICE}>No default (choose each time)</SelectItem>
                {VOICE_CATALOG.map((v) => (
                  <SelectItem key={v.id} value={v.id}>
                    {v.name}
                    {v.accent ? ` · ${v.accent}` : ""}
                    {v.description ? ` — ${v.description}` : ""}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="space-y-2">
            <Label htmlFor="default-language">Default language</Label>
            <Select value={language} onValueChange={setLanguage}>
              <SelectTrigger id="default-language">
                <SelectValue placeholder="Choose a language" />
              </SelectTrigger>
              <SelectContent>
                {LANGUAGES.map((l) => (
                  <SelectItem key={l.code} value={l.code}>
                    {l.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <Button onClick={saveDefaults} disabled={savingDefaults}>
            {savingDefaults ? <Loader2 className="h-4 w-4 animate-spin" /> : <Save className="h-4 w-4" />}
            Save defaults
          </Button>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>Notifications</CardTitle>
          <CardDescription>Choose which emails you want to receive.</CardDescription>
        </CardHeader>
        <CardContent className="space-y-1">
          <div className="flex items-center justify-between gap-4 py-3">
            <div className="space-y-0.5">
              <p className="text-sm font-semibold">Episode ready</p>
              <p className="text-xs text-muted-foreground">
                Email me when an episode finishes generating.
              </p>
            </div>
            <Switch
              checked={emailOnReady}
              disabled={savingNotif}
              onCheckedChange={(v) => saveNotifications({ emailOnEpisodeReady: v })}
              aria-label="Email me when an episode is ready"
            />
          </div>
          <div className="flex items-center justify-between gap-4 border-t py-3">
            <div className="space-y-0.5">
              <p className="text-sm font-semibold">Product updates</p>
              <p className="text-xs text-muted-foreground">
                Occasional product news, tips and announcements.
              </p>
            </div>
            <Switch
              checked={productEmails}
              disabled={savingNotif}
              onCheckedChange={(v) => saveNotifications({ productEmails: v })}
              aria-label="Receive product update emails"
            />
          </div>
        </CardContent>
      </Card>

      <Card className="border-destructive/30">
        <CardHeader>
          <CardTitle className="text-destructive">Danger zone</CardTitle>
          <CardDescription>
            Permanently delete your account and all of your episodes. This cannot be undone.
          </CardDescription>
        </CardHeader>
        <CardContent>
          <ConfirmDialog
            trigger={<Button variant="destructive">Delete account</Button>}
            title="Delete your account?"
            description="This permanently deletes your account, every episode, series, and all generated content. This action is irreversible."
            confirmLabel="Delete my account"
            successMessage="Account deleted"
            body={
              <div className="space-y-2">
                <Label htmlFor="confirm-email">
                  Type <span className="font-semibold text-foreground">{email}</span> to confirm
                </Label>
                <Input
                  id="confirm-email"
                  value={confirmEmail}
                  onChange={(e) => setConfirmEmail(e.target.value)}
                  placeholder={email}
                  autoComplete="off"
                />
              </div>
            }
            onConfirm={async () => {
              const res = await deleteAccountAction(confirmEmail);
              if (res.ok) {
                await signOut();
                router.push("/");
              }
              return res;
            }}
          />
        </CardContent>
      </Card>
    </div>
  );
}
