import React from 'react';
import { Loader2, ShieldCheck, ShieldX, Mail, User as UserIcon, Globe, Lock } from 'lucide-react';
import toast from 'react-hot-toast';
import { useTranslation } from 'react-i18next';

import { AdminLayout } from '../components/AdminLayout';
import { useAuth } from '../auth/context';
import {
  fetchTenantProfile,
  updateTenantProfile,
  type TenantAccountProfile,
  type UpdateTenantProfilePayload,
} from '../api';
import { getApiErrorMessage, isApiError } from '../lib/apiError';

import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';

type FieldErrors = Record<string, string>;

function extractFieldErrors(error: unknown): FieldErrors {
  if (isApiError(error) && error.meta && typeof error.meta.errors === 'object') {
    const entries = error.meta.errors as Record<string, unknown>;
    const mapped: FieldErrors = {};

    Object.entries(entries).forEach(([key, value]) => {
      if (Array.isArray(value) && value.length > 0 && typeof value[0] === 'string') {
        mapped[key] = value[0];
      }
    });

    return mapped;
  }

  return {};
}

const DEFAULT_LOCALES = ['de', 'en'];
const AUTO_LOCALE_OPTION = '__auto__';

export default function ProfilePage(): JSX.Element {
  const { t } = useTranslation(['settings', 'common']);
  const { refreshProfile } = useAuth();

  const [profile, setProfile] = React.useState<TenantAccountProfile | null>(null);
  const [loading, setLoading] = React.useState(true);

  const [infoForm, setInfoForm] = React.useState({
    name: '',
    email: '',
    preferred_locale: '',
  });

  const [passwordForm, setPasswordForm] = React.useState({
    current_password: '',
    password: '',
    password_confirmation: '',
  });

  const [infoErrors, setInfoErrors] = React.useState<FieldErrors>({});
  const [passwordErrors, setPasswordErrors] = React.useState<FieldErrors>({});
  const [savingInfo, setSavingInfo] = React.useState(false);
  const [savingPassword, setSavingPassword] = React.useState(false);

  const availableLocales = React.useMemo(() => {
    const candidates = new Set(DEFAULT_LOCALES);
    if (typeof document !== 'undefined') {
      const lang = document.documentElement.lang;
      if (lang) {
        const short = lang.toLowerCase().split('-')[0];
        candidates.add(short);
      }
    }
    if (profile?.preferred_locale) {
      candidates.add(profile.preferred_locale.toLowerCase());
    }
    return Array.from(candidates).sort();
  }, [profile?.preferred_locale]);

  const selectedLocale = infoForm.preferred_locale && infoForm.preferred_locale !== '' ? infoForm.preferred_locale : AUTO_LOCALE_OPTION;

  React.useEffect(() => {
    let cancelled = false;

    async function loadProfile(): Promise<void> {
      setLoading(true);
      try {
        const data = await fetchTenantProfile();
        if (cancelled) {
          return;
        }
        setProfile(data);
        setInfoForm({
          name: data.name ?? '',
          email: data.email ?? '',
          preferred_locale: data.preferred_locale ?? '',
        });
      } catch (error) {
        if (!cancelled) {
          toast.error(getApiErrorMessage(error, t('settings:profile.errors.load', 'Profil konnte nicht geladen werden.')));
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    }

    void loadProfile();

    return () => {
      cancelled = true;
    };
  }, [t]);

  const handleInfoSubmit = React.useCallback(
    async (event: React.FormEvent<HTMLFormElement>) => {
      event.preventDefault();
      setInfoErrors({});
      setSavingInfo(true);

      const payload: UpdateTenantProfilePayload = {
        name: infoForm.name,
        email: infoForm.email,
        preferred_locale: infoForm.preferred_locale || null,
      };

      try {
        const updated = await updateTenantProfile(payload);
        setProfile(updated);
        toast.success(t('settings:profile.toasts.updated', 'Profil wurde aktualisiert.'));
        setInfoForm({
          name: updated.name ?? '',
          email: updated.email ?? '',
          preferred_locale: updated.preferred_locale ?? '',
        });
        setPasswordForm((prev) => ({ ...prev, current_password: '' }));
        await refreshProfile();
      } catch (error) {
        const message = getApiErrorMessage(error, t('settings:profile.errors.update', 'Profil konnte nicht aktualisiert werden.'));
        toast.error(message);
        const fieldErrors = extractFieldErrors(error);
        if (Object.keys(fieldErrors).length > 0) {
          setInfoErrors(fieldErrors);
        }
      } finally {
        setSavingInfo(false);
      }
    },
    [infoForm.email, infoForm.name, infoForm.preferred_locale, refreshProfile, t]
  );

  const handlePasswordSubmit = React.useCallback(
    async (event: React.FormEvent<HTMLFormElement>) => {
      event.preventDefault();
      setPasswordErrors({});
      setSavingPassword(true);

      const payload: UpdateTenantProfilePayload = {
        name: infoForm.name,
        email: infoForm.email,
        preferred_locale: infoForm.preferred_locale || null,
        current_password: passwordForm.current_password || undefined,
        password: passwordForm.password || undefined,
        password_confirmation: passwordForm.password_confirmation || undefined,
      };

      try {
        const updated = await updateTenantProfile(payload);
        setProfile(updated);
        toast.success(t('settings:profile.toasts.passwordChanged', 'Passwort wurde aktualisiert.'));
        setPasswordForm({ current_password: '', password: '', password_confirmation: '' });
        await refreshProfile();
      } catch (error) {
        const message = getApiErrorMessage(error, t('settings:profile.errors.update', 'Profil konnte nicht aktualisiert werden.'));
        toast.error(message);
        const fieldErrors = extractFieldErrors(error);
        if (Object.keys(fieldErrors).length > 0) {
          setPasswordErrors(fieldErrors);
        }
      } finally {
        setSavingPassword(false);
      }
    },
    [infoForm.email, infoForm.name, infoForm.preferred_locale, passwordForm, refreshProfile, t]
  );

  if (loading) {
    return (
      <AdminLayout title={t('settings:profile.title', 'Profil')} subtitle={t('settings:profile.subtitle', 'Verwalte Accountangaben und Zugangsdaten.')}>
        <div className="flex min-h-[320px] items-center justify-center">
          <div className="flex items-center gap-2 text-sm text-muted-foreground">
            <Loader2 className="h-5 w-5 animate-spin" />
            {t('common:loading', 'Wird geladen …')}
          </div>
        </div>
      </AdminLayout>
    );
  }

  if (!profile) {
    return (
      <AdminLayout title={t('settings:profile.title', 'Profil')} subtitle={t('settings:profile.subtitle', 'Verwalte Accountangaben und Zugangsdaten.')}>
        <div className="rounded-3xl border border-rose-200/60 bg-rose-50/70 p-8 text-center text-sm text-rose-600">
          {t('settings:profile.errors.load', 'Profil konnte nicht geladen werden.')}
        </div>
      </AdminLayout>
    );
  }

  return (
    <AdminLayout
      title={t('settings:profile.title', 'Profil')}
      subtitle={t('settings:profile.subtitle', 'Verwalte Accountangaben und Zugangsdaten.')}
    >
      <Card className="border-0 bg-white/90 shadow-xl shadow-rose-100/60">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-xl text-slate-900">
            <UserIcon className="h-5 w-5 text-rose-500" />
            {t('settings:profile.sections.account.heading', 'Account-Informationen')}
          </CardTitle>
          <CardDescription className="text-sm text-slate-600">
            {t('settings:profile.sections.account.description', 'Passe Name, E-Mail und Sprache deiner Admin-Oberfläche an.')}
          </CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={handleInfoSubmit} className="space-y-6">
            <div className="grid gap-6 sm:grid-cols-2">
              <div className="space-y-2">
                <Label htmlFor="profile-name" className="flex items-center gap-2 text-sm font-semibold text-slate-800">
                  <UserIcon className="h-4 w-4 text-rose-500" />
                  {t('settings:profile.fields.name', 'Anzeigename')}
                </Label>
                <Input
                  id="profile-name"
                  value={infoForm.name}
                  onChange={(event) => setInfoForm((prev) => ({ ...prev, name: event.target.value }))}
                  placeholder={t('settings:profile.placeholders.name', 'z. B. Hochzeitsplanung Schmidt')}
                />
                {infoErrors.name && <p className="text-sm text-rose-500">{infoErrors.name}</p>}
              </div>

              <div className="space-y-2">
                <Label htmlFor="profile-email" className="flex items-center gap-2 text-sm font-semibold text-slate-800">
                  <Mail className="h-4 w-4 text-rose-500" />
                  {t('settings:profile.fields.email', 'E-Mail-Adresse')}
                </Label>
                <Input
                  id="profile-email"
                  type="email"
                  value={infoForm.email}
                  onChange={(event) => setInfoForm((prev) => ({ ...prev, email: event.target.value }))}
                  placeholder="admin@example.com"
                />
                {infoErrors.email && <p className="text-sm text-rose-500">{infoErrors.email}</p>}
              </div>
            </div>

            <div className="grid gap-6 sm:grid-cols-2">
              <div className="space-y-2">
                <Label htmlFor="profile-locale" className="flex items-center gap-2 text-sm font-semibold text-slate-800">
                  <Globe className="h-4 w-4 text-rose-500" />
                  {t('settings:profile.fields.locale', 'Bevorzugte Sprache')}
                </Label>
                <Select
                  value={selectedLocale}
                  onValueChange={(value) =>
                    setInfoForm((prev) => ({ ...prev, preferred_locale: value === AUTO_LOCALE_OPTION ? '' : value }))
                  }
                >
                  <SelectTrigger id="profile-locale" aria-label={t('settings:profile.fields.locale', 'Bevorzugte Sprache')}>
                    <SelectValue placeholder={t('settings:profile.placeholders.locale', 'Systemsprache verwenden')} />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value={AUTO_LOCALE_OPTION}>{t('settings:profile.locale.auto', 'Automatisch')}</SelectItem>
                    {availableLocales.map((locale) => (
                      <SelectItem key={locale} value={locale} className="capitalize">
                        {locale}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                {infoErrors.preferred_locale && <p className="text-sm text-rose-500">{infoErrors.preferred_locale}</p>}
              </div>

              <div className="space-y-2">
                <Label className="flex items-center gap-2 text-sm font-semibold text-slate-800">
                  {profile.email_verified ? (
                    <>
                      <ShieldCheck className="h-4 w-4 text-emerald-500" />
                      {t('settings:profile.status.emailVerified', 'E-Mail bestätigt')}
                    </>
                  ) : (
                    <>
                      <ShieldX className="h-4 w-4 text-rose-500" />
                      {t('settings:profile.status.emailNotVerified', 'Bestätigung erforderlich')}
                    </>
                  )}
                </Label>
                <div className="rounded-2xl border border-slate-200/70 bg-slate-50/70 p-3 text-sm text-slate-600">
                  {profile.email_verified
                    ? t('settings:profile.status.verifiedHint', 'Bestätigt am {{date}}.', {
                        date: profile.email_verified_at ? new Date(profile.email_verified_at).toLocaleString() : '',
                      })
                    : t('settings:profile.status.unverifiedHint', 'Wir senden dir eine neue Bestätigung, sobald du die E-Mail änderst.')}
                </div>
              </div>
            </div>

            <div className="flex flex-wrap gap-3">
              <Button type="submit" disabled={savingInfo} className="flex items-center gap-2">
                {savingInfo && <Loader2 className="h-4 w-4 animate-spin" />}
                {t('settings:profile.actions.save', 'Speichern')}
              </Button>
              <Button
                type="button"
                variant="ghost"
                onClick={() => {
                  if (!profile) {
                    return;
                  }
                  setInfoForm({
                    name: profile.name ?? '',
                    email: profile.email ?? '',
                    preferred_locale: profile.preferred_locale ?? '',
                  });
                  setInfoErrors({});
                }}
              >
                {t('common:actions.reset', 'Zurücksetzen')}
              </Button>
            </div>
          </form>
        </CardContent>
      </Card>

      <Card className="border-0 bg-white/90 shadow-xl shadow-indigo-100/50">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-xl text-slate-900">
            <Lock className="h-5 w-5 text-indigo-500" />
            {t('settings:profile.sections.password.heading', 'Passwort ändern')}
          </CardTitle>
          <CardDescription className="text-sm text-slate-600">
            {t('settings:profile.sections.password.description', 'Wähle ein sicheres Passwort, um dein Admin-Konto zu schützen.')}
          </CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={handlePasswordSubmit} className="space-y-6">
            <div className="grid gap-6 sm:grid-cols-3">
              <div className="space-y-2">
                <Label htmlFor="profile-current-password" className="text-sm font-semibold text-slate-800">
                  {t('settings:profile.fields.currentPassword', 'Aktuelles Passwort')}
                </Label>
                <Input
                  id="profile-current-password"
                  type="password"
                  autoComplete="current-password"
                  value={passwordForm.current_password}
                  onChange={(event) => setPasswordForm((prev) => ({ ...prev, current_password: event.target.value }))}
                />
                {passwordErrors.current_password && <p className="text-sm text-rose-500">{passwordErrors.current_password}</p>}
              </div>

              <div className="space-y-2">
                <Label htmlFor="profile-new-password" className="text-sm font-semibold text-slate-800">
                  {t('settings:profile.fields.newPassword', 'Neues Passwort')}
                </Label>
                <Input
                  id="profile-new-password"
                  type="password"
                  autoComplete="new-password"
                  value={passwordForm.password}
                  onChange={(event) => setPasswordForm((prev) => ({ ...prev, password: event.target.value }))}
                />
                {passwordErrors.password && <p className="text-sm text-rose-500">{passwordErrors.password}</p>}
              </div>

              <div className="space-y-2">
                <Label htmlFor="profile-password-confirmation" className="text-sm font-semibold text-slate-800">
                  {t('settings:profile.fields.passwordConfirmation', 'Passwort bestätigen')}
                </Label>
                <Input
                  id="profile-password-confirmation"
                  type="password"
                  autoComplete="new-password"
                  value={passwordForm.password_confirmation}
                  onChange={(event) => setPasswordForm((prev) => ({ ...prev, password_confirmation: event.target.value }))}
                />
                {passwordErrors.password_confirmation && <p className="text-sm text-rose-500">{passwordErrors.password_confirmation}</p>}
              </div>
            </div>

            <div className="rounded-2xl border border-slate-200/70 bg-slate-50/70 p-4 text-xs text-slate-600">
              {t('settings:profile.sections.password.hint', 'Dein Passwort muss mindestens 8 Zeichen lang sein und eine Mischung aus Buchstaben und Zahlen enthalten.')}
            </div>

            <div className="flex flex-wrap gap-3">
              <Button type="submit" variant="secondary" disabled={savingPassword} className="flex items-center gap-2">
                {savingPassword && <Loader2 className="h-4 w-4 animate-spin" />}
                {t('settings:profile.actions.updatePassword', 'Passwort aktualisieren')}
              </Button>
              <Button
                type="button"
                variant="ghost"
                onClick={() => {
                  setPasswordForm({ current_password: '', password: '', password_confirmation: '' });
                  setPasswordErrors({});
                }}
              >
                {t('common:actions.reset', 'Zurücksetzen')}
              </Button>
            </div>
          </form>
        </CardContent>
      </Card>
    </AdminLayout>
  );
}
