/*
 * SCR-48 마이페이지·환경설정. 참조: UIWS auth/MyProfilePage.
 * 좌: 탭 레일(프로필·보안·알림설정·테마/언어) / 우: 설정 폼.
 * 백엔드: /api/auth/me·/api/auth/me/*(프로필·비밀번호·알림설정)·/api/auth/otp/status.
 *   2FA는 기존 /otp-setup 화면으로 연결(중복 구현 금지).
 * GAP G-08 해소: 프로필 수정(PUT /api/auth/me)·비밀번호 변경(POST /api/auth/me/password)·
 *   알림설정 서버 동기화(GET/PUT /api/auth/me/notification-prefs). 테마/언어만 클라이언트 로컬 저장.
 */
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useAuthStore } from '../../store/authStore';
import { Button } from '../../components/ui/Button';
import { RoleBadge } from '../../components/ui/Badge';
import { ErrorState, Skeleton } from '../../components/ui/States';
import { IconBell, IconCheckCircle, IconSettings, IconShieldCheck, IconUser } from '../../components/ui/icons';
import { authApi } from '../../api/endpoints';
import { useToast, errMessage } from './workShared';
import { myPageApi, type NotificationPrefs } from './myPageApi';
import './work.css';

type Tab = 'profile' | 'security' | 'notify' | 'theme';
const TABS: { v: Tab; l: string }[] = [
  { v: 'profile', l: '프로필' },
  { v: 'security', l: '보안(2차 인증)' },
  { v: 'notify', l: '알림 설정' },
  { v: 'theme', l: '테마·언어' },
];

const PREF_KEY = 'kintex.prefs';
interface Prefs {
  theme: 'light' | 'dark';
  lang: 'ko' | 'en' | 'zh' | 'ja';
}
const DEFAULT_PREFS: Prefs = { theme: 'light', lang: 'ko' };

function loadPrefs(): Prefs {
  try {
    return { ...DEFAULT_PREFS, ...JSON.parse(localStorage.getItem(PREF_KEY) ?? '{}') };
  } catch {
    return DEFAULT_PREFS;
  }
}

const NOTIFY_ROWS: { key: keyof NotificationPrefs; label: string }[] = [
  { key: 'notifyDeadline', label: '마감 D-데이 알림' },
  { key: 'notifyApproval', label: '승인·검수 알림' },
  { key: 'notifyPayment', label: '결제·정산 알림' },
  { key: 'emailEnabled', label: '이메일 병행 발송' },
];

export function MyPage() {
  const { show, node: toast } = useToast();
  const qc = useQueryClient();
  const storeUser = useAuthStore((s) => s.user);
  const workspaces = useAuthStore((s) => s.workspaces);
  const [tab, setTab] = useState<Tab>('profile');
  const [prefs, setPrefs] = useState<Prefs>(loadPrefs);

  const meQ = useQuery({ queryKey: ['me'], queryFn: () => myPageApi.me() });
  const otpQ = useQuery({ queryKey: ['otp-status'], queryFn: () => authApi.otpStatus() });

  // ── 프로필 편집 폼 상태(서버 로드 시 동기화) ──
  const [name, setName] = useState('');
  const [phone, setPhone] = useState('');
  useEffect(() => {
    if (meQ.data) {
      setName(meQ.data.displayName ?? '');
      setPhone(meQ.data.phone ?? '');
    }
  }, [meQ.data]);

  const profileMut = useMutation({
    mutationFn: () => myPageApi.updateProfile({ displayName: name.trim(), phone: phone.trim() }),
    onSuccess: (updated) => {
      qc.setQueryData(['me'], updated);
      qc.invalidateQueries({ queryKey: ['me'] });
      show('프로필이 저장되었습니다.');
    },
    onError: (e) => show(errMessage(e)),
  });

  // ── 비밀번호 변경 상태 ──
  const [curPw, setCurPw] = useState('');
  const [newPw, setNewPw] = useState('');
  const [confirmPw, setConfirmPw] = useState('');
  const pwMut = useMutation({
    mutationFn: () => myPageApi.changePassword({ currentPassword: curPw, newPassword: newPw }),
    onSuccess: () => {
      setCurPw('');
      setNewPw('');
      setConfirmPw('');
      show('비밀번호가 변경되었습니다.');
    },
    onError: (e) => show(errMessage(e)),
  });
  function submitPassword() {
    if (newPw.length < 8) {
      show('새 비밀번호는 8자 이상이어야 합니다.');
      return;
    }
    if (newPw !== confirmPw) {
      show('새 비밀번호가 일치하지 않습니다.');
      return;
    }
    if (newPw === curPw) {
      show('새 비밀번호는 현재 비밀번호와 달라야 합니다.');
      return;
    }
    pwMut.mutate();
  }

  // ── 알림 설정(서버 동기화) ──
  const notifQ = useQuery({ queryKey: ['notif-prefs'], queryFn: () => myPageApi.getNotificationPrefs() });
  const notifMut = useMutation({
    mutationFn: (next: NotificationPrefs) => myPageApi.saveNotificationPrefs(next),
    onSuccess: (saved) => {
      qc.setQueryData(['notif-prefs'], saved);
      show('알림 설정이 저장되었습니다.');
    },
    onError: (e) => {
      qc.invalidateQueries({ queryKey: ['notif-prefs'] }); // 실패 시 서버 값으로 롤백
      show(errMessage(e));
    },
  });
  function toggleNotify(key: keyof NotificationPrefs, value: boolean) {
    if (!notifQ.data) return;
    const next = { ...notifQ.data, [key]: value };
    qc.setQueryData(['notif-prefs'], next); // 낙관적 반영
    notifMut.mutate(next);
  }

  function savePrefs(next: Prefs) {
    setPrefs(next);
    localStorage.setItem(PREF_KEY, JSON.stringify(next));
    show('설정이 저장되었습니다.');
  }

  useEffect(() => {
    document.documentElement.setAttribute('data-theme', prefs.theme);
    document.documentElement.setAttribute('lang', prefs.lang);
  }, [prefs.theme, prefs.lang]);

  const displayName = meQ.data?.displayName ?? storeUser?.displayName ?? '사용자';
  const roles = Array.from(new Set(workspaces.map((w) => w.myRole).filter(Boolean)));
  const dirty = name.trim() !== (meQ.data?.displayName ?? '') || phone.trim() !== (meQ.data?.phone ?? '');

  return (
    <div className="kx-page">
      <header className="kx-work__head">
        <div>
          <h1 className="kx-work__title">마이페이지</h1>
          <p className="kx-work__subtitle">프로필 · 보안 · 알림 · 환경설정</p>
        </div>
      </header>

      <div className="kx-my">
        <nav className="kx-my__rail" aria-label="설정 탭">
          {TABS.map((t) => (
            <button
              key={t.v}
              className={`kx-my__rail-btn ${tab === t.v ? 'is-active' : ''}`}
              onClick={() => setTab(t.v)}
            >
              {t.l}
            </button>
          ))}
        </nav>

        <section className="kx-card" aria-label="설정 내용">
          {/* 프로필 */}
          {tab === 'profile' && (
            <>
              <div className="kx-card__head">
                <h2><IconUser className="kx-title-ic" size={18} />프로필</h2>
              </div>
              {meQ.isLoading ? (
                <Skeleton height={80} />
              ) : meQ.isError ? (
                <ErrorState onRetry={() => meQ.refetch()} />
              ) : (
                <>
                  <div style={{ display: 'flex', gap: 20, alignItems: 'center', flexWrap: 'wrap' }}>
                    <span className="kx-my__avatar">{displayName[0] ?? '·'}</span>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                      <span className="kx-list-table__muted">사용자 ID: {meQ.data?.userId}</span>
                      {meQ.data?.email && (
                        <span className="kx-list-table__muted">{meQ.data.email}</span>
                      )}
                      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                        {meQ.data?.hallManager && <span className="kx-pill kx-pill--info">홀매니저</span>}
                        {roles.map((r, i) => (
                          <RoleBadge key={i} role={r} />
                        ))}
                      </div>
                      <span className="kx-list-table__muted">참여 행사 {workspaces.length}건</span>
                    </div>
                  </div>

                  <div className="kx-formgrid" style={{ marginTop: 16 }}>
                    <label className="kx-field">
                      <span className="kx-label">이름</span>
                      <input
                        className="kx-input"
                        value={name}
                        maxLength={120}
                        onChange={(e) => setName(e.target.value)}
                        placeholder="표시 이름"
                      />
                    </label>
                    <label className="kx-field">
                      <span className="kx-label">연락처</span>
                      <input
                        className="kx-input"
                        value={phone}
                        maxLength={40}
                        onChange={(e) => setPhone(e.target.value)}
                        placeholder="예: 010-1234-5678"
                        inputMode="tel"
                      />
                    </label>
                    <label className="kx-field">
                      <span className="kx-label">이메일(변경 불가)</span>
                      <input className="kx-input" value={meQ.data?.email ?? ''} disabled readOnly />
                    </label>
                  </div>
                  <div style={{ marginTop: 12 }}>
                    <Button
                      onClick={() => profileMut.mutate()}
                      disabled={!dirty || !name.trim() || profileMut.isPending}
                    >
                      {profileMut.isPending ? '저장 중…' : '프로필 저장'}
                    </Button>
                  </div>
                </>
              )}
            </>
          )}

          {/* 보안 (2FA + 비밀번호 변경) */}
          {tab === 'security' && (
            <>
              <div className="kx-card__head">
                <h2><IconShieldCheck className="kx-title-ic" size={18} />2차 인증(OTP)</h2>
              </div>
              {otpQ.isLoading ? (
                <Skeleton height={60} />
              ) : (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    {otpQ.data?.otpEnabled ? (
                      <>
                        <span style={{ color: 'var(--color-success)', display: 'inline-flex' }}>
                          <IconCheckCircle size={20} />
                        </span>
                        <span>2차 인증이 활성화되어 있습니다.</span>
                      </>
                    ) : (
                      <span className="kx-pill kx-pill--warn">2차 인증 미설정</span>
                    )}
                  </div>
                  <p className="kx-list-table__muted" style={{ fontSize: 13 }}>
                    Google Authenticator 등 TOTP 앱으로 로그인 2단계 인증을 사용합니다.
                    등록·재설정은 전용 화면에서 진행합니다.
                  </p>
                  <div>
                    <Link to="/otp-setup">
                      <Button>{otpQ.data?.otpEnabled ? '2차 인증 재설정' : '2차 인증 등록'}</Button>
                    </Link>
                  </div>
                </div>
              )}

              <div className="kx-card__head" style={{ marginTop: 24 }}>
                <h2><IconShieldCheck className="kx-title-ic" size={18} />비밀번호 변경</h2>
              </div>
              <div className="kx-formgrid">
                <label className="kx-field">
                  <span className="kx-label">현재 비밀번호</span>
                  <input
                    className="kx-input"
                    type="password"
                    value={curPw}
                    autoComplete="current-password"
                    onChange={(e) => setCurPw(e.target.value)}
                  />
                </label>
                <label className="kx-field">
                  <span className="kx-label">새 비밀번호(8자 이상)</span>
                  <input
                    className="kx-input"
                    type="password"
                    value={newPw}
                    autoComplete="new-password"
                    onChange={(e) => setNewPw(e.target.value)}
                  />
                </label>
                <label className="kx-field">
                  <span className="kx-label">새 비밀번호 확인</span>
                  <input
                    className="kx-input"
                    type="password"
                    value={confirmPw}
                    autoComplete="new-password"
                    onChange={(e) => setConfirmPw(e.target.value)}
                  />
                </label>
              </div>
              <div style={{ marginTop: 12 }}>
                <Button
                  onClick={submitPassword}
                  disabled={!curPw || !newPw || !confirmPw || pwMut.isPending}
                >
                  {pwMut.isPending ? '변경 중…' : '비밀번호 변경'}
                </Button>
              </div>
            </>
          )}

          {/* 알림 설정 */}
          {tab === 'notify' && (
            <>
              <div className="kx-card__head">
                <h2><IconBell className="kx-title-ic" size={18} />알림 설정</h2>
              </div>
              {notifQ.isLoading ? (
                <Skeleton height={120} />
              ) : notifQ.isError ? (
                <ErrorState onRetry={() => notifQ.refetch()} />
              ) : (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                  {NOTIFY_ROWS.map(({ key, label }) => (
                    <label className="kx-switch" key={key}>
                      <input
                        type="checkbox"
                        checked={notifQ.data?.[key] ?? false}
                        disabled={notifMut.isPending}
                        onChange={(e) => toggleNotify(key, e.target.checked)}
                      />
                      <span>{label}</span>
                    </label>
                  ))}
                  <p className="kx-list-table__muted" style={{ fontSize: 12 }}>
                    알림 설정은 서버에 저장되어 모든 기기에 동일하게 적용됩니다.
                  </p>
                </div>
              )}
            </>
          )}

          {/* 테마·언어 */}
          {tab === 'theme' && (
            <>
              <div className="kx-card__head">
                <h2><IconSettings className="kx-title-ic" size={18} />테마·언어</h2>
              </div>
              <div className="kx-formgrid">
                <label className="kx-field">
                  <span className="kx-label">테마</span>
                  <div className="kx-seg" role="tablist">
                    {(['light', 'dark'] as const).map((t) => (
                      <button
                        key={t}
                        className={`kx-seg__btn ${prefs.theme === t ? 'is-active' : ''}`}
                        onClick={() => savePrefs({ ...prefs, theme: t })}
                      >
                        {t === 'light' ? '라이트' : '다크'}
                      </button>
                    ))}
                  </div>
                </label>
                <label className="kx-field">
                  <span className="kx-label">언어</span>
                  <select
                    className="kx-select"
                    value={prefs.lang}
                    onChange={(e) => savePrefs({ ...prefs, lang: e.target.value as Prefs['lang'] })}
                  >
                    <option value="ko">한국어</option>
                    <option value="en">English</option>
                    <option value="zh">中文</option>
                    <option value="ja">日本語</option>
                  </select>
                </label>
              </div>
              <p className="kx-list-table__muted" style={{ marginTop: 12, fontSize: 12 }}>
                테마·언어는 이 기기에 저장됩니다. 다국어 리소스는 순차 적용 예정입니다.
              </p>
            </>
          )}
        </section>
      </div>
      {toast}
    </div>
  );
}
