import React from 'react';
import { useTranslation } from 'react-i18next';
import { CheckCircle2, Lock, MailWarning, User } from 'lucide-react';
import { YStack, XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Pressable } from '@tamagui/react-native-web-lite';
import toast from 'react-hot-toast';
import { MobileShell } from './components/MobileShell';
import { MobileCard, CTAButton, PillBadge } from './components/Primitives';
import { MobileField, MobileInput, MobileSelect, MobileColorInput } from './components/FormControls';
import {
  fetchTenantProfile,
  updateTenantProfile,
  getTenantPackagesOverview,
  getTenantSettings,
  updateTenantSettings,
  type TenantAccountProfile,
} from '../api';
import { getApiErrorMessage, getApiValidationMessage } from '../lib/apiError';
import { ADMIN_PROFILE_PATH } from '../constants';
import { useBackNavigation } from './hooks/useBackNavigation';
import { useAdminTheme } from './theme';
import i18n from '../i18n';
import { extractBrandingForm, type BrandingFormValues } from '../lib/brandingForm';
import { DEFAULT_EVENT_BRANDING } from '@/guest/context/EventBrandingContext';

type ProfileFormState = {
  name: string;
  email: string;
  preferredLocale: string;
  currentPassword: string;
  password: string;
  passwordConfirmation: string;
};

const LOCALE_OPTIONS = [
  { value: '', labelKey: 'profile.locale.auto', fallback: 'Automatisch' },
  { value: 'de', label: 'Deutsch' },
  { value: 'en', label: 'English' },
];

type TabKey = 'account' | 'branding';

const TENANT_BRANDING_DEFAULTS = {
  primary: DEFAULT_EVENT_BRANDING.primaryColor,
  accent: DEFAULT_EVENT_BRANDING.secondaryColor,
  background: DEFAULT_EVENT_BRANDING.backgroundColor,
  surface: DEFAULT_EVENT_BRANDING.palette?.surface ?? DEFAULT_EVENT_BRANDING.backgroundColor,
  headingFont: DEFAULT_EVENT_BRANDING.typography?.heading ?? DEFAULT_EVENT_BRANDING.fontFamily ?? '',
  bodyFont: DEFAULT_EVENT_BRANDING.typography?.body ?? DEFAULT_EVENT_BRANDING.fontFamily ?? '',
  mode: DEFAULT_EVENT_BRANDING.mode ?? 'auto',
  buttonStyle: DEFAULT_EVENT_BRANDING.buttons?.style ?? 'filled',
  buttonRadius: DEFAULT_EVENT_BRANDING.buttons?.radius ?? 12,
  buttonPrimary: DEFAULT_EVENT_BRANDING.buttons?.primary ?? DEFAULT_EVENT_BRANDING.primaryColor,
  buttonSecondary: DEFAULT_EVENT_BRANDING.buttons?.secondary ?? DEFAULT_EVENT_BRANDING.secondaryColor,
  linkColor: DEFAULT_EVENT_BRANDING.buttons?.linkColor ?? DEFAULT_EVENT_BRANDING.secondaryColor,
  welcomeMessage: '',
  fontSize: DEFAULT_EVENT_BRANDING.typography?.sizePreset ?? 'm',
  logoMode: DEFAULT_EVENT_BRANDING.logo?.mode ?? 'emoticon',
  logoPosition: DEFAULT_EVENT_BRANDING.logo?.position ?? 'left',
  logoSize: DEFAULT_EVENT_BRANDING.logo?.size ?? 'm',
};

const buildTenantBrandingFormBase = (): BrandingFormValues => ({
  ...TENANT_BRANDING_DEFAULTS,
  logoDataUrl: '',
  logoValue: '',
});

export default function MobileProfileAccountPage() {
  const { t } = useTranslation('settings');
  const { text, muted, danger, subtle, primary, accentSoft } = useAdminTheme();
  const back = useBackNavigation(ADMIN_PROFILE_PATH);

  const [profile, setProfile] = React.useState<TenantAccountProfile | null>(null);
  const [activeTab, setActiveTab] = React.useState<TabKey>('account');
  const [brandingAllowed, setBrandingAllowed] = React.useState(false);
  const [brandingLoading, setBrandingLoading] = React.useState(true);
  const [brandingSaving, setBrandingSaving] = React.useState(false);
  const [brandingError, setBrandingError] = React.useState<string | null>(null);
  const [tenantSettings, setTenantSettings] = React.useState<Record<string, unknown> | null>(null);
  const [brandingForm, setBrandingForm] = React.useState<BrandingFormValues>(buildTenantBrandingFormBase);
  const [form, setForm] = React.useState<ProfileFormState>({
    name: '',
    email: '',
    preferredLocale: '',
    currentPassword: '',
    password: '',
    passwordConfirmation: '',
  });
  const [loading, setLoading] = React.useState(true);
  const [savingAccount, setSavingAccount] = React.useState(false);
  const [savingPassword, setSavingPassword] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);
  const loadErrorMessage = t('profile.errors.load', 'Profil konnte nicht geladen werden.');
  const brandingLoadError = t('profile.errors.brandingLoad', 'Standard-Branding konnte nicht geladen werden.');
  const brandingSaveError = t('profile.errors.brandingSave', 'Standard-Branding konnte nicht gespeichert werden.');

  const dateFormatter = React.useMemo(
    () =>
      new Intl.DateTimeFormat(i18n.language || 'de', {
        day: '2-digit',
        month: 'long',
        year: 'numeric',
      }),
    [i18n.language],
  );

  React.useEffect(() => {
    (async () => {
      setLoading(true);
      try {
        const data = await fetchTenantProfile();
        setProfile(data);
        setForm((prev) => ({
          ...prev,
          name: data.name ?? '',
          email: data.email ?? '',
          preferredLocale: data.preferred_locale ?? '',
        }));
        setError(null);
      } catch (err) {
        setError(getApiErrorMessage(err, loadErrorMessage));
      } finally {
        setLoading(false);
      }
    })();
  }, []);

  React.useEffect(() => {
    let active = true;
    (async () => {
      try {
        const overview = await getTenantPackagesOverview();
        if (!active) return;
        setBrandingAllowed(Boolean(overview.activePackage?.branding_allowed));
      } catch {
        if (active) {
          setBrandingAllowed(false);
        }
      }
    })();

    return () => {
      active = false;
    };
  }, []);

  React.useEffect(() => {
    let active = true;
    (async () => {
      setBrandingLoading(true);
      try {
        const payload = await getTenantSettings();
        if (!active) return;
        const settings = (payload.settings ?? {}) as Record<string, unknown>;
        setTenantSettings(settings);
        setBrandingForm(extractBrandingForm(settings, TENANT_BRANDING_DEFAULTS));
        setBrandingError(null);
      } catch (err) {
        if (active) {
          setBrandingError(getApiErrorMessage(err, brandingLoadError));
        }
      } finally {
        if (active) {
          setBrandingLoading(false);
        }
      }
    })();

    return () => {
      active = false;
    };
  }, [brandingLoadError]);

  const verifiedAt = profile?.email_verified_at ? new Date(profile.email_verified_at) : null;
  const verifiedDate = verifiedAt ? dateFormatter.format(verifiedAt) : null;
  const emailStatusLabel = profile?.email_verified
    ? t('profile.status.emailVerified', 'E-Mail bestätigt')
    : t('profile.status.emailNotVerified', 'Bestätigung erforderlich');
  const emailHint = profile?.email_verified
    ? t('profile.status.verifiedHint', 'Bestätigt am {{date}}.', { date: verifiedDate ?? '' })
    : t('profile.status.unverifiedHint', 'Bei Änderung der E-Mail senden wir dir automatisch eine neue Bestätigung.');
  const brandingTabEnabled = brandingAllowed;

  React.useEffect(() => {
    if (!brandingTabEnabled && activeTab === 'branding') {
      setActiveTab('account');
    }
  }, [brandingTabEnabled, activeTab]);

  const buildPayload = (includePassword: boolean) => ({
    name: form.name.trim(),
    email: form.email.trim(),
    preferred_locale: form.preferredLocale ? form.preferredLocale : null,
    ...(includePassword
      ? {
          current_password: form.currentPassword,
          password: form.password,
          password_confirmation: form.passwordConfirmation,
        }
      : {}),
  });

  const handleAccountSave = async () => {
    setSavingAccount(true);
    try {
      const updated = await updateTenantProfile(buildPayload(false));
      setProfile(updated);
      setError(null);
      toast.success(t('profile.toasts.updated', 'Profil wurde aktualisiert.'));
    } catch (err) {
      const message = getApiValidationMessage(err, t('profile.errors.update', 'Profil konnte nicht aktualisiert werden.'));
      setError(message);
      toast.error(message);
    } finally {
      setSavingAccount(false);
    }
  };

  const handlePasswordSave = async () => {
    setSavingPassword(true);
    try {
      const updated = await updateTenantProfile(buildPayload(true));
      setProfile(updated);
      setError(null);
      setForm((prev) => ({
        ...prev,
        currentPassword: '',
        password: '',
        passwordConfirmation: '',
      }));
      toast.success(t('profile.toasts.passwordChanged', 'Passwort wurde aktualisiert.'));
    } catch (err) {
      const message = getApiValidationMessage(err, t('profile.errors.update', 'Profil konnte nicht aktualisiert werden.'));
      setError(message);
      toast.error(message);
    } finally {
      setSavingPassword(false);
    }
  };

  const handleBrandingSave = async () => {
    if (!tenantSettings) {
      return;
    }
    setBrandingSaving(true);
    try {
      const existingBranding =
        tenantSettings && typeof (tenantSettings as Record<string, unknown>).branding === 'object'
          ? ((tenantSettings as Record<string, unknown>).branding as Record<string, unknown>)
          : {};
      const settings = {
        ...tenantSettings,
        branding: {
          ...existingBranding,
          primary_color: brandingForm.primary,
          secondary_color: brandingForm.accent,
          accent_color: brandingForm.accent,
          background_color: brandingForm.background,
          surface_color: brandingForm.surface,
          font_family: brandingForm.bodyFont,
          heading_font: brandingForm.headingFont,
          body_font: brandingForm.bodyFont,
          font_size: brandingForm.fontSize,
          mode: brandingForm.mode,
          welcome_message: brandingForm.welcomeMessage.trim() ? brandingForm.welcomeMessage.trim() : null,
          typography: {
            ...(typeof existingBranding.typography === 'object' ? (existingBranding.typography as Record<string, unknown>) : {}),
            heading: brandingForm.headingFont,
            body: brandingForm.bodyFont,
            size: brandingForm.fontSize,
          },
          palette: {
            ...(typeof existingBranding.palette === 'object' ? (existingBranding.palette as Record<string, unknown>) : {}),
            primary: brandingForm.primary,
            secondary: brandingForm.accent,
            background: brandingForm.background,
            surface: brandingForm.surface,
          },
        },
      };
      const updated = await updateTenantSettings(settings);
      const nextSettings = (updated.settings ?? {}) as Record<string, unknown>;
      setTenantSettings(nextSettings);
      setBrandingForm(extractBrandingForm(nextSettings, TENANT_BRANDING_DEFAULTS));
      setBrandingError(null);
      toast.success(t('profile.branding.updated', 'Standard-Branding gespeichert.'));
    } catch (err) {
      const message = getApiErrorMessage(err, brandingSaveError);
      setBrandingError(message);
      toast.error(message);
    } finally {
      setBrandingSaving(false);
    }
  };

  const passwordReady =
    form.currentPassword.trim().length > 0 &&
    form.password.trim().length > 0 &&
    form.passwordConfirmation.trim().length > 0;
  const brandingDisabled = brandingLoading || brandingSaving;

  return (
    <MobileShell
      activeTab="profile"
      title={t('profile.title', 'Profil')}
      onBack={back}
    >
      {brandingTabEnabled ? (
        <XStack gap="$2">
          <TabButton
            label={t('profile.tabs.account', 'Account')}
            active={activeTab === 'account'}
            onPress={() => setActiveTab('account')}
          />
          <TabButton
            label={t('profile.tabs.branding', 'Standard-Branding')}
            active={activeTab === 'branding'}
            onPress={() => setActiveTab('branding')}
          />
        </XStack>
      ) : null}

      {activeTab === 'branding' && brandingTabEnabled ? (
        <>
          {brandingError ? (
            <MobileCard>
              <Text fontWeight="700" color={danger}>
                {brandingError}
              </Text>
            </MobileCard>
          ) : null}

          <MobileCard gap="$3">
            <Text fontSize="$md" fontWeight="800" color={text}>
              {t('profile.branding.title', 'Standard-Branding')}
            </Text>
            <Text fontSize="$sm" color={muted}>
              {t('profile.branding.hint', 'Diese Werte dienen als Vorschlag für neue Events und beschleunigen die Einrichtung.')}
            </Text>
          </MobileCard>

          <MobileCard gap="$3">
            <Text fontSize="$md" fontWeight="800" color={text}>
              {t('profile.branding.theme', 'Theme')}
            </Text>
            <YStack gap="$3">
              <MobileField label={t('events.branding.mode', 'Theme')}>
                <MobileSelect
                  value={brandingForm.mode}
                  onChange={(event) => setBrandingForm((prev) => ({ ...prev, mode: event.target.value as BrandingFormValues['mode'] }))}
                  disabled={brandingDisabled}
                >
                  <option value="light">{t('events.branding.modeLight', 'Light')}</option>
                  <option value="auto">{t('events.branding.modeAuto', 'Auto')}</option>
                  <option value="dark">{t('events.branding.modeDark', 'Dark')}</option>
                </MobileSelect>
              </MobileField>
              <MobileField label={t('events.branding.fontSize', 'Font Size')}>
                <MobileSelect
                  value={brandingForm.fontSize}
                  onChange={(event) => setBrandingForm((prev) => ({ ...prev, fontSize: event.target.value as BrandingFormValues['fontSize'] }))}
                  disabled={brandingDisabled}
                >
                  <option value="s">{t('events.branding.fontSizeSmall', 'S')}</option>
                  <option value="m">{t('events.branding.fontSizeMedium', 'M')}</option>
                  <option value="l">{t('events.branding.fontSizeLarge', 'L')}</option>
                </MobileSelect>
              </MobileField>
            </YStack>
          </MobileCard>

          <MobileCard gap="$3">
            <Text fontSize="$md" fontWeight="800" color={text}>
              {t('events.branding.colors', 'Colors')}
            </Text>
            <YStack gap="$3">
              <ColorField
                label={t('events.branding.primary', 'Primary Color')}
                value={brandingForm.primary}
                onChange={(value) => setBrandingForm((prev) => ({ ...prev, primary: value }))}
                disabled={brandingDisabled}
              />
              <ColorField
                label={t('events.branding.accent', 'Accent Color')}
                value={brandingForm.accent}
                onChange={(value) => setBrandingForm((prev) => ({ ...prev, accent: value }))}
                disabled={brandingDisabled}
              />
              <ColorField
                label={t('events.branding.backgroundColor', 'Background Color')}
                value={brandingForm.background}
                onChange={(value) => setBrandingForm((prev) => ({ ...prev, background: value }))}
                disabled={brandingDisabled}
              />
              <ColorField
                label={t('events.branding.surfaceColor', 'Surface Color')}
                value={brandingForm.surface}
                onChange={(value) => setBrandingForm((prev) => ({ ...prev, surface: value }))}
                disabled={brandingDisabled}
              />
            </YStack>
          </MobileCard>

          <MobileCard gap="$3">
            <Text fontSize="$md" fontWeight="800" color={text}>
              {t('events.branding.fonts', 'Fonts')}
            </Text>
            <YStack gap="$3">
              <MobileField label={t('events.branding.headingFont', 'Headline Font')}>
                <MobileInput
                  value={brandingForm.headingFont}
                  onChange={(event) => setBrandingForm((prev) => ({ ...prev, headingFont: event.target.value }))}
                  placeholder={t('events.branding.headingFontPlaceholder', 'Playfair Display')}
                  hasError={false}
                  disabled={brandingDisabled}
                />
              </MobileField>
              <MobileField label={t('events.branding.bodyFont', 'Body Font')}>
                <MobileInput
                  value={brandingForm.bodyFont}
                  onChange={(event) => setBrandingForm((prev) => ({ ...prev, bodyFont: event.target.value }))}
                  placeholder={t('events.branding.bodyFontPlaceholder', 'Montserrat')}
                  hasError={false}
                  disabled={brandingDisabled}
                />
              </MobileField>
            </YStack>
          </MobileCard>

          <CTAButton
            label={brandingSaving ? t('profile.branding.saving', 'Saving...') : t('profile.branding.save', 'Save defaults')}
            onPress={handleBrandingSave}
            disabled={brandingDisabled}
            loading={brandingSaving}
          />
        </>
      ) : (
        <>
          {error ? (
            <MobileCard>
              <Text fontWeight="700" color={danger}>
                {error}
              </Text>
            </MobileCard>
          ) : null}

          <MobileCard gap="$3">
            <XStack alignItems="center" gap="$3">
              <XStack
                width={48}
                height={48}
                borderRadius={16}
                alignItems="center"
                justifyContent="center"
                backgroundColor={accentSoft}
              >
                <User size={20} color={primary} />
              </XStack>
              <YStack gap="$1">
                <Text fontSize="$md" fontWeight="800" color={text}>
                  {form.name || profile?.email || t('profile.title', 'Profil')}
                </Text>
                <Text fontSize="$sm" color={muted}>
                  {form.email || profile?.email || '—'}
                </Text>
              </YStack>
            </XStack>
            <XStack alignItems="center" gap="$2" flexWrap="wrap">
              {profile?.email_verified ? (
                <CheckCircle2 size={14} color={subtle} />
              ) : (
                <MailWarning size={14} color={subtle} />
              )}
              <PillBadge tone={profile?.email_verified ? 'success' : 'warning'}>
                {emailStatusLabel}
              </PillBadge>
              <Text fontSize="$xs" color={muted}>
                {emailHint}
              </Text>
            </XStack>
          </MobileCard>

          <MobileCard gap="$3">
            <XStack alignItems="center" gap="$2">
              <User size={16} color={text} />
              <Text fontSize="$md" fontWeight="800" color={text}>
                {t('profile.sections.account.heading', 'Account-Informationen')}
              </Text>
            </XStack>
            <Text fontSize="$sm" color={muted}>
              {t('profile.sections.account.description', 'Passe Anzeigename, E-Mail-Adresse und Sprache der Admin-Oberfläche an.')}
            </Text>
            {loading ? (
              <Text fontSize="$sm" color={muted}>
                {t('profile.loading', 'Lädt ...')}
              </Text>
            ) : (
              <YStack gap="$3">
                <MobileField label={t('profile.fields.name', 'Anzeigename')}>
                  <MobileInput
                    value={form.name}
                    onChange={(event) => setForm((prev) => ({ ...prev, name: event.target.value }))}
                    placeholder={t('profile.placeholders.name', 'z. B. Hochzeitsplanung Schmidt')}
                    hasError={false}
                  />
                </MobileField>
                <MobileField label={t('profile.fields.email', 'E-Mail-Adresse')}>
                  <MobileInput
                    value={form.email}
                    onChange={(event) => setForm((prev) => ({ ...prev, email: event.target.value }))}
                    placeholder="mail@beispiel.de"
                    type="email"
                    hasError={false}
                  />
                </MobileField>
                <MobileField label={t('profile.fields.locale', 'Bevorzugte Sprache')}>
                  <MobileSelect
                    value={form.preferredLocale}
                    onChange={(event) => setForm((prev) => ({ ...prev, preferredLocale: event.target.value }))}
                  >
                    {LOCALE_OPTIONS.map((option) => (
                      <option key={option.value} value={option.value}>
                        {option.label ?? t(option.labelKey, option.fallback)}
                      </option>
                    ))}
                  </MobileSelect>
                </MobileField>
                <CTAButton
                  label={t('profile.actions.save', 'Speichern')}
                  onPress={handleAccountSave}
                  disabled={savingAccount || loading}
                  loading={savingAccount}
                />
              </YStack>
            )}
          </MobileCard>

          <MobileCard gap="$3">
            <XStack alignItems="center" gap="$2">
              <Lock size={16} color={text} />
              <Text fontSize="$md" fontWeight="800" color={text}>
                {t('profile.sections.password.heading', 'Passwort ändern')}
              </Text>
            </XStack>
            <Text fontSize="$sm" color={muted}>
              {t('profile.sections.password.description', 'Wähle ein sicheres Passwort, um deinen Admin-Zugang zu schützen.')}
            </Text>
            <YStack gap="$3">
              <MobileField label={t('profile.fields.currentPassword', 'Aktuelles Passwort')}>
                <MobileInput
                  value={form.currentPassword}
                  onChange={(event) => setForm((prev) => ({ ...prev, currentPassword: event.target.value }))}
                  placeholder="••••••••"
                  type="password"
                  hasError={false}
                />
              </MobileField>
              <MobileField
                label={t('profile.fields.newPassword', 'Neues Passwort')}
                hint={t('profile.sections.password.hint', 'Nutze mindestens 8 Zeichen und kombiniere Buchstaben sowie Zahlen für mehr Sicherheit.')}
              >
                <MobileInput
                  value={form.password}
                  onChange={(event) => setForm((prev) => ({ ...prev, password: event.target.value }))}
                  placeholder="••••••••"
                  type="password"
                  hasError={false}
                />
              </MobileField>
              <MobileField label={t('profile.fields.passwordConfirmation', 'Passwort bestätigen')}>
                <MobileInput
                  value={form.passwordConfirmation}
                  onChange={(event) => setForm((prev) => ({ ...prev, passwordConfirmation: event.target.value }))}
                  placeholder="••••••••"
                  type="password"
                  hasError={false}
                />
              </MobileField>
              <CTAButton
                label={t('profile.actions.updatePassword', 'Passwort aktualisieren')}
                onPress={handlePasswordSave}
                disabled={!passwordReady || savingPassword || loading}
                loading={savingPassword}
                tone="ghost"
              />
            </YStack>
          </MobileCard>
        </>
      )}
    </MobileShell>
  );
}

function TabButton({ label, active, onPress }: { label: string; active: boolean; onPress: () => void }) {
  const { primary, surfaceMuted, border, surface, text } = useAdminTheme();
  return (
    <Pressable onPress={onPress} style={{ flex: 1 }}>
      <XStack
        alignItems="center"
        justifyContent="center"
        paddingVertical="$2.5"
        borderRadius={12}
        backgroundColor={active ? primary : surfaceMuted}
        borderWidth={1}
        borderColor={active ? primary : border}
      >
        <Text fontSize="$sm" color={active ? surface : text} fontWeight="700">
          {label}
        </Text>
      </XStack>
    </Pressable>
  );
}

function ColorField({
  label,
  value,
  onChange,
  disabled,
}: {
  label: string;
  value: string;
  onChange: (next: string) => void;
  disabled?: boolean;
}) {
  const { text, muted } = useAdminTheme();
  return (
    <YStack gap="$2" opacity={disabled ? 0.6 : 1}>
      <Text fontSize="$sm" fontWeight="700" color={text}>
        {label}
      </Text>
      <XStack alignItems="center" gap="$2">
        <MobileColorInput
          value={value}
          onChange={(event) => onChange(event.target.value)}
          disabled={disabled}
        />
        <Text fontSize="$sm" color={muted}>
          {value}
        </Text>
      </XStack>
    </YStack>
  );
}
