import { useState } from 'react';
import { QRCodeSVG } from 'qrcode.react';
import { errorMessage } from '../../api/client';
import {
  Alert,
  Badge,
  Button,
  Card,
  FormField,
  Input,
  Spinner,
  useToast,
} from '@cameleer/design-system';
import {
  useTenantSettings, useChangeOwnPassword, useResetServerAdminPassword,
  useMfaStatus, useMfaSetup, useMfaVerify, useMfaBackupCodes, useMfaRemove,
  useUpdateTenantSettings,
} from '../../api/tenant-hooks';
import { useScopes } from '../../auth/useScopes';
import { tierColor } from '../../utils/tier';
import styles from '../../styles/platform.module.css';

function statusColor(status: string): 'success' | 'error' | 'warning' | 'auto' {
  switch (status?.toUpperCase()) {
    case 'ACTIVE': return 'success';
    case 'SUSPENDED': return 'warning';
    case 'PROVISIONING': return 'auto';
    case 'ERROR': return 'error';
    default: return 'auto';
  }
}

function MfaSection() {
  const { toast } = useToast();
  const { data: mfaStatus, isLoading: statusLoading } = useMfaStatus();
  const setup = useMfaSetup();
  const verify = useMfaVerify();
  const backupCodes = useMfaBackupCodes();
  const remove = useMfaRemove();

  const [setupData, setSetupData] = useState<{ secret: string; secretQrCode: string } | null>(null);
  const [verifyCode, setVerifyCode] = useState('');
  const [codes, setCodes] = useState<string[] | null>(null);
  const [codesSaved, setCodesSaved] = useState(false);
  const [confirmRemove, setConfirmRemove] = useState(false);

  async function handleStartSetup() {
    try {
      const data = await setup.mutateAsync();
      setSetupData(data);
      setVerifyCode('');
    } catch (err) {
      toast({ title: 'Failed to start MFA setup', description: errorMessage(err), variant: 'error' });
    }
  }

  async function handleVerify(e: React.FormEvent) {
    e.preventDefault();
    if (!setupData) return;
    try {
      const result = await verify.mutateAsync({ secret: setupData.secret, code: verifyCode });
      if (result.verified) {
        const bc = await backupCodes.mutateAsync();
        setCodes(bc.codes);
        setSetupData(null);
        setVerifyCode('');
        setCodesSaved(false);
        toast({ title: 'MFA enabled successfully', variant: 'success' });
      } else {
        toast({ title: 'Invalid code. Please try again.', variant: 'error' });
      }
    } catch (err) {
      toast({ title: 'Verification failed', description: errorMessage(err), variant: 'error' });
    }
  }

  async function handleRegenerateCodes() {
    try {
      const bc = await backupCodes.mutateAsync();
      setCodes(bc.codes);
      setCodesSaved(false);
      toast({ title: 'Backup codes regenerated', variant: 'success' });
    } catch (err) {
      toast({ title: 'Failed to regenerate backup codes', description: errorMessage(err), variant: 'error' });
    }
  }

  async function handleRemove() {
    try {
      await remove.mutateAsync();
      setConfirmRemove(false);
      setCodes(null);
      setSetupData(null);
      toast({ title: 'MFA removed', variant: 'success' });
    } catch (err) {
      toast({ title: 'Failed to remove MFA', description: errorMessage(err), variant: 'error' });
    }
  }

  function handleCopyAll() {
    if (!codes) return;
    navigator.clipboard.writeText(codes.join('\n'));
    toast({ title: 'Backup codes copied to clipboard', variant: 'success' });
  }

  function handleDownload() {
    if (!codes) return;
    const blob = new Blob([codes.join('\n')], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'cameleer-mfa-backup-codes.txt';
    a.click();
    URL.revokeObjectURL(url);
  }

  if (statusLoading) {
    return (
      <Card title="Multi-Factor Authentication">
        <div style={{ display: 'flex', justifyContent: 'center', padding: 24 }}>
          <Spinner />
        </div>
      </Card>
    );
  }

  // Backup codes display
  if (codes) {
    return (
      <Card title="Multi-Factor Authentication">
        <Alert variant="warning" title="Save your backup codes">
          These codes can be used to sign in if you lose access to your authenticator app. Each code can only be used once. Store them in a safe place.
        </Alert>
        <div style={{
          display: 'grid',
          gridTemplateColumns: '1fr 1fr',
          gap: '8px 24px',
          marginTop: 16,
          padding: '16px',
          background: 'var(--bg-inset)',
          border: '1px solid var(--border)',
          borderRadius: 6,
          fontFamily: 'var(--font-mono, monospace)',
          fontSize: '0.875rem',
        }}>
          {codes.map((code) => (
            <span key={code}>{code}</span>
          ))}
        </div>
        <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>
          <Button variant="secondary" onClick={handleCopyAll}>Copy all</Button>
          <Button variant="secondary" onClick={handleDownload}>Download .txt</Button>
        </div>
        <label style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 16, fontSize: '0.875rem', cursor: 'pointer' }}>
          <input type="checkbox" checked={codesSaved} onChange={(e) => setCodesSaved(e.target.checked)} />
          I've saved my backup codes
        </label>
        <div style={{ marginTop: 12 }}>
          <Button variant="primary" disabled={!codesSaved} onClick={() => setCodes(null)}>
            Done
          </Button>
        </div>
      </Card>
    );
  }

  // Setup flow — QR code + verification
  if (setupData) {
    return (
      <Card title="Multi-Factor Authentication">
        <p className={styles.description} style={{ marginTop: 0 }}>
          Scan this QR code with your authenticator app (Google Authenticator, Authy, 1Password, etc.), then enter the 6-digit code below.
        </p>
        <div style={{ display: 'flex', justifyContent: 'center', padding: '16px 0' }}>
          <QRCodeSVG value={setupData.secretQrCode} size={200} />
        </div>
        <div style={{
          textAlign: 'center',
          padding: '8px 12px',
          background: 'var(--bg-inset)',
          border: '1px solid var(--border)',
          borderRadius: 6,
          fontFamily: 'var(--font-mono, monospace)',
          fontSize: '0.75rem',
          wordBreak: 'break-all',
          marginBottom: 16,
        }}>
          {setupData.secret}
        </div>
        <form onSubmit={handleVerify} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <FormField label="Verification code" htmlFor="mfa-code">
            <Input
              id="mfa-code"
              type="text"
              inputMode="numeric"
              maxLength={6}
              pattern="[0-9]{6}"
              value={verifyCode}
              onChange={(e) => setVerifyCode(e.target.value.replace(/\D/g, '').slice(0, 6))}
              placeholder="Enter 6-digit code"
              required
              autoComplete="one-time-code"
            />
          </FormField>
          <div style={{ display: 'flex', gap: 8 }}>
            <Button type="submit" variant="primary" loading={verify.isPending || backupCodes.isPending} disabled={verifyCode.length !== 6}>
              Verify & Enable
            </Button>
            <Button type="button" variant="secondary" onClick={() => { setSetupData(null); setVerifyCode(''); }}>
              Cancel
            </Button>
          </div>
        </form>
      </Card>
    );
  }

  // Main view — enrolled or not
  return (
    <Card title="Multi-Factor Authentication">
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12 }}>
        <span className={styles.description} style={{ margin: 0 }}>Status:</span>
        {mfaStatus?.enrolled ? (
          <Badge label="Enrolled" color="success" />
        ) : (
          <Badge label="Not enrolled" color="auto" />
        )}
      </div>
      {mfaStatus?.enrolled ? (
        <>
          <p className={styles.description} style={{ marginTop: 0 }}>
            Your account is protected with a TOTP authenticator app.
          </p>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            <Button variant="secondary" onClick={handleRegenerateCodes} loading={backupCodes.isPending}>
              Regenerate backup codes
            </Button>
            {confirmRemove ? (
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <Alert variant="error" title="This will disable MFA on your account." />
                <Button variant="danger" onClick={handleRemove} loading={remove.isPending}>
                  Confirm removal
                </Button>
                <Button variant="secondary" onClick={() => setConfirmRemove(false)}>
                  Cancel
                </Button>
              </div>
            ) : (
              <Button variant="danger" onClick={() => setConfirmRemove(true)}>
                Remove MFA
              </Button>
            )}
          </div>
        </>
      ) : (
        <>
          <p className={styles.description} style={{ marginTop: 0 }}>
            Add an extra layer of security to your account by enabling multi-factor authentication with an authenticator app.
          </p>
          <div>
            <Button variant="primary" onClick={handleStartSetup} loading={setup.isPending}>
              Set up authenticator app
            </Button>
          </div>
        </>
      )}
    </Card>
  );
}

function MfaEnforcementToggle() {
  const scopes = useScopes();
  const { toast } = useToast();
  const { data: settings } = useTenantSettings();
  const updateSettings = useUpdateTenantSettings();
  const [confirmEnable, setConfirmEnable] = useState(false);

  if (!scopes.has('tenant:manage')) return null;

  const mfaRequired = settings?.mfaRequired ?? false;

  async function handleToggle() {
    if (!mfaRequired) {
      setConfirmEnable(true);
      return;
    }
    try {
      await updateSettings.mutateAsync({ mfaRequired: false });
      toast({ title: 'MFA requirement disabled for all members', variant: 'success' });
    } catch (err) {
      toast({ title: 'Failed to update MFA setting', description: errorMessage(err), variant: 'error' });
    }
  }

  async function handleConfirmEnable() {
    try {
      await updateSettings.mutateAsync({ mfaRequired: true });
      setConfirmEnable(false);
      toast({ title: 'MFA is now required for all members', variant: 'success' });
    } catch (err) {
      toast({ title: 'Failed to update MFA setting', description: errorMessage(err), variant: 'error' });
    }
  }

  return (
    <Card title="MFA Enforcement">
      <p className={styles.description} style={{ marginTop: 0 }}>
        When enabled, all team members will be required to set up multi-factor authentication before accessing this tenant.
      </p>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
        <span style={{ fontSize: '0.875rem' }}>Require MFA for all members</span>
        <Badge label={mfaRequired ? 'Required' : 'Optional'} color={mfaRequired ? 'success' : 'auto'} />
      </div>
      {confirmEnable ? (
        <div style={{ marginTop: 12 }}>
          <Alert variant="warning" title="Confirm MFA requirement">
            All team members who have not enrolled in MFA will need to set it up on their next login. Are you sure?
          </Alert>
          <div style={{ display: 'flex', gap: 8, marginTop: 12 }}>
            <Button variant="primary" onClick={handleConfirmEnable} loading={updateSettings.isPending}>
              Yes, require MFA
            </Button>
            <Button variant="secondary" onClick={() => setConfirmEnable(false)}>
              Cancel
            </Button>
          </div>
        </div>
      ) : (
        <div style={{ marginTop: 12 }}>
          <Button
            variant={mfaRequired ? 'danger' : 'primary'}
            onClick={handleToggle}
            loading={updateSettings.isPending}
          >
            {mfaRequired ? 'Disable MFA requirement' : 'Enable MFA requirement'}
          </Button>
        </div>
      )}
    </Card>
  );
}

export function SettingsPage() {
  const { data, isLoading, isError } = useTenantSettings();
  const changePassword = useChangeOwnPassword();
  const resetServerAdmin = useResetServerAdminPassword();
  const { toast } = useToast();

  const [newPassword, setNewPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [serverAdminPw, setServerAdminPw] = useState('');

  async function handleChangePassword(e: React.FormEvent) {
    e.preventDefault();
    if (newPassword.length < 8) {
      toast({ title: 'Password must be at least 8 characters', variant: 'error' });
      return;
    }
    if (newPassword !== confirmPassword) {
      toast({ title: 'Passwords do not match', variant: 'error' });
      return;
    }
    try {
      await changePassword.mutateAsync(newPassword);
      toast({ title: 'Password changed successfully', variant: 'success' });
      setNewPassword('');
      setConfirmPassword('');
    } catch (err) {
      toast({ title: 'Failed to change password', description: errorMessage(err), variant: 'error' });
    }
  }

  if (isLoading) {
    return (
      <div style={{ display: 'flex', justifyContent: 'center', padding: 64 }}>
        <Spinner />
      </div>
    );
  }

  if (isError || !data) {
    return (
      <div style={{ padding: 24 }}>
        <Alert variant="error" title="Failed to load settings">
          Could not fetch settings. Please refresh.
        </Alert>
      </div>
    );
  }

  return (
    <div style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 20 }}>
      <h1 style={{ margin: 0, fontSize: '1.25rem', fontWeight: 600 }}>Settings</h1>

      <Card title="Tenant Details">
        <div className={styles.dividerList}>
          <div className={styles.kvRow}>
            <span className={styles.kvLabel}>Name</span>
            <span className={styles.kvValue}>{data.name}</span>
          </div>
          <div className={styles.kvRow}>
            <span className={styles.kvLabel}>Slug</span>
            <span className={styles.kvValueMono}>{data.slug}</span>
          </div>
          <div className={styles.kvRow}>
            <span className={styles.kvLabel}>Tier</span>
            <Badge label={data.tier} color={tierColor(data.tier)} />
          </div>
          <div className={styles.kvRow}>
            <span className={styles.kvLabel}>Status</span>
            <Badge label={data.status} color={statusColor(data.status)} />
          </div>
          <div className={styles.kvRow}>
            <span className={styles.kvLabel}>Server Endpoint</span>
            <span className={styles.kvValueMono}>{data.serverEndpoint ?? '—'}</span>
          </div>
          <div className={styles.kvRow}>
            <span className={styles.kvLabel}>Created</span>
            <span className={styles.kvValue}>{new Date(data.createdAt).toLocaleDateString()}</span>
          </div>
        </div>

        <p className={styles.description} style={{ marginTop: 16 }}>
          To change your tier or other billing-related settings, please contact support.
        </p>
      </Card>

      <Card title="Change Password">
        <p className={styles.description} style={{ marginTop: 0 }}>
          Update your login password. Minimum 8 characters.
        </p>
        <form onSubmit={handleChangePassword} style={{ display: 'flex', flexDirection: 'column', gap: 16, marginTop: 12 }}>
          <FormField label="New password" htmlFor="new-pw">
            <Input
              id="new-pw"
              type="password"
              value={newPassword}
              onChange={(e) => setNewPassword(e.target.value)}
              placeholder="Enter new password"
              required
              minLength={8}
            />
          </FormField>
          <FormField label="Confirm password" htmlFor="confirm-pw">
            <Input
              id="confirm-pw"
              type="password"
              value={confirmPassword}
              onChange={(e) => setConfirmPassword(e.target.value)}
              placeholder="Confirm new password"
              required
              minLength={8}
            />
          </FormField>
          <div>
            <Button type="submit" variant="primary" loading={changePassword.isPending}>
              Change Password
            </Button>
          </div>
        </form>
      </Card>

      <Card title="Server Admin Password">
        <p className={styles.description} style={{ marginTop: 0 }}>
          Reset the built-in admin password for your server dashboard (local login at <code>/login?local</code>).
        </p>
        <form
          onSubmit={async (e) => {
            e.preventDefault();
            if (serverAdminPw.length < 8) {
              toast({ title: 'Password must be at least 8 characters', variant: 'error' });
              return;
            }
            try {
              await resetServerAdmin.mutateAsync(serverAdminPw);
              toast({ title: 'Server admin password reset successfully', variant: 'success' });
              setServerAdminPw('');
            } catch (err) {
              toast({ title: 'Failed to reset server admin password', description: errorMessage(err), variant: 'error' });
            }
          }}
          style={{ display: 'flex', flexDirection: 'column', gap: 16, marginTop: 12 }}
        >
          <FormField label="New admin password" htmlFor="server-admin-pw">
            <Input
              id="server-admin-pw"
              type="password"
              value={serverAdminPw}
              onChange={(e) => setServerAdminPw(e.target.value)}
              placeholder="Enter new admin password"
              required
              minLength={8}
            />
          </FormField>
          <div>
            <Button type="submit" variant="primary" loading={resetServerAdmin.isPending}>
              Reset Admin Password
            </Button>
          </div>
        </form>
      </Card>

      <MfaSection />
      <MfaEnforcementToggle />
    </div>
  );
}
