'use client';

import { useState } from 'react';
import axios from '@/network/axios';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogBody,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';

/**
 * Change the signed-in admin's password.
 *
 * The portal had no way to do this: its own NextAuth password flow is not
 * wired to the platform's users, and the menu's profile links are template
 * pages. This posts to the platform backend's /change-password (the same
 * endpoint the main app uses), which checks the current password itself.
 */
const MIN_LENGTH = 12;

function weakness(pw: string): string | null {
  if (pw.length < MIN_LENGTH) return `At least ${MIN_LENGTH} characters.`;
  if (!/[a-z]/i.test(pw) || !/\d/.test(pw)) return 'Use letters and numbers.';
  return null;
}

export function ChangePasswordDialog({
  open,
  onOpenChange,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const [current, setCurrent] = useState('');
  const [next, setNext] = useState('');
  const [confirm, setConfirm] = useState('');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const reset = () => {
    setCurrent('');
    setNext('');
    setConfirm('');
    setError(null);
  };

  const submit = async () => {
    const weak = weakness(next);
    if (!current) return setError('Enter your current password.');
    if (weak) return setError(weak);
    if (next !== confirm) return setError('The new passwords do not match.');

    setSaving(true);
    setError(null);
    try {
      await axios.post('/change-password', {
        current_password: current,
        new_password: next,
        new_password_confirmation: confirm,
      });
      toast.success('Password changed.');
      reset();
      onOpenChange(false);
    } catch (e: unknown) {
      const res = (e as { response?: { data?: { message?: string; errors?: Record<string, string[]> } } })
        .response?.data;
      const first = res?.errors ? Object.values(res.errors)[0]?.[0] : null;
      setError(first || res?.message || 'Could not change the password.');
    } finally {
      setSaving(false);
    }
  };

  return (
    <Dialog
      open={open}
      onOpenChange={(o) => {
        if (!o) reset();
        onOpenChange(o);
      }}
    >
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>Change password</DialogTitle>
          <DialogDescription>
            At least {MIN_LENGTH} characters, with letters and numbers.
          </DialogDescription>
        </DialogHeader>
        <DialogBody className="flex flex-col gap-4">
          <div className="flex flex-col gap-1.5">
            <Label htmlFor="cp-current">Current password</Label>
            <Input id="cp-current" type="password" autoComplete="current-password" value={current} onChange={(e) => setCurrent(e.target.value)} />
          </div>
          <div className="flex flex-col gap-1.5">
            <Label htmlFor="cp-new">New password</Label>
            <Input id="cp-new" type="password" autoComplete="new-password" value={next} onChange={(e) => setNext(e.target.value)} />
          </div>
          <div className="flex flex-col gap-1.5">
            <Label htmlFor="cp-confirm">Confirm new password</Label>
            <Input
              id="cp-confirm"
              type="password"
              autoComplete="new-password"
              value={confirm}
              onChange={(e) => setConfirm(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && submit()}
            />
          </div>
          {error && <p className="text-sm text-destructive">{error}</p>}
        </DialogBody>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={saving}>
            Cancel
          </Button>
          <Button onClick={submit} disabled={saving}>
            {saving ? 'Saving…' : 'Change password'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
