import { useEffect, useState, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Card, CardContent, CardHeader, CardTitle } from '@shared/components/ui/card';
import { Badge } from '@shared/components/ui/badge';
import { Button } from '@shared/components/ui/button';
import { PageContainer, PageHeader } from '@shared/components/layout';
import { DataTable, type DataColumn } from '@shared/components/common/DataTable';
import {
  Shield, Users, UserCheck, Key, Lock, FileText, Loader2, RefreshCw, UserCog,
} from 'lucide-react';
import {
  fetchUsers,
  fetchUserStats,
  fetchAuditLogs,
  fetchAuditStats,
  unlockUser,
  type AdminUser,
  type UserStats,
  type AuditLog as ApiAuditLog,
  type AuditStats,
} from '@/services/adminApi';
import { formatDateTime } from '@shared/utils/dateFormat';
import { getRoleBadgeStyle } from '@shared/constants/userRoles';
import { getUserAccountStatusIntent, getUserAccountStatusLabel } from '@shared/constants/userAccountStatuses';
import { useSettingsStore } from '@stores/settingsStore';
import { PermissionsPanel } from './PermissionsPanel';
import { UserRoleAssignDialog } from './UserRoleAssignDialog';

/*
 * SFR-01: 역할 기반 권한 관리(RBAC) - 백엔드 연동 버전
 *
 * 4개 탭:
 *   1) 역할 관리   - GET /api/roles (admin:role-management) + 사용자 통계
 *   2) 사용자 관리 - GET /api/admin/users + 잠금 해제
 *   3) 감사 로그   - GET /api/admin/audit-logs + GET /api/admin/stats/audit
 *   4) 보안 정책   - 정적 정보
 */

type Tab = 'roles' | 'users' | 'audit' | 'policy';

export function AccessControl() {
  const { t } = useTranslation('admin');
  const { t: tc } = useTranslation('common');
  const lang = useSettingsStore((s) => s.language);
  const [tab, setTab] = useState<Tab>('roles');

  // 공통 상태
  const [error, setError] = useState('');

  // 사용자 목록
  const [users, setUsers] = useState<AdminUser[]>([]);
  const [userStats, setUserStats] = useState<UserStats | null>(null);
  const [usersLoading, setUsersLoading] = useState(false);

  // 감사 로그
  const [auditLogs, setAuditLogs] = useState<ApiAuditLog[]>([]);
  const [auditStats, setAuditStats] = useState<AuditStats | null>(null);
  const [auditLoading, setAuditLoading] = useState(false);

  // 역할 배정 다이얼로그
  const [assignTarget, setAssignTarget] = useState<AdminUser | null>(null);

  // 사용자 + 통계 로드
  const loadUsers = useCallback(async () => {
    setUsersLoading(true); setError('');
    try {
      const [u, s] = await Promise.all([fetchUsers(), fetchUserStats()]);
      setUsers(u);
      setUserStats(s);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'unknown');
    } finally {
      setUsersLoading(false);
    }
  }, []);

  const loadAudit = useCallback(async () => {
    setAuditLoading(true); setError('');
    try {
      const [logs, stats] = await Promise.all([fetchAuditLogs(0, 100), fetchAuditStats()]);
      setAuditLogs(logs.content);
      setAuditStats(stats);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'unknown');
    } finally {
      setAuditLoading(false);
    }
  }, []);

  // 탭 전환 시 자동 로드 (roles 탭은 PermissionsPanel이 자체 로드)
  useEffect(() => {
    if (tab === 'users') loadUsers();
    else if (tab === 'audit') loadAudit();
  }, [tab, loadUsers, loadAudit]);

  const handleUnlock = async (userId: string, acnt: string) => {
    if (!confirm(`계정 ${acnt} 잠금을 해제하시겠습니까?`)) return;
    try {
      await unlockUser(userId);
      await loadUsers();
    } catch (e: unknown) {
      alert('실패: ' + (e instanceof Error ? e.message : 'unknown'));
    }
  };

  // ── 사용자 테이블 컬럼 ──────────────
   
  const userColumns: DataColumn<AdminUser & Record<string, unknown>>[] = useMemo(() => [
    { key: 'userAcnt', label: '계정', width: '90px',
      render: (v) => <span className="text-label font-mono text-[11px]">{v as string}</span> },
    { key: 'userNm', label: '이름', width: '80px', sortable: true,
      render: (v) => <span className="text-heading font-medium">{v as string}</span> },
    { key: 'rnkpNm', label: '직급', width: '60px',
      render: (v) => <span className="text-muted-foreground">{(v as string) || '-'}</span> },
    { key: 'email', label: '이메일',
      render: (v) => <span className="text-muted-foreground text-[10px]">{(v as string) || '-'}</span> },
    { key: 'roles', label: '역할', width: '120px',
      render: (v) => {
        const list = (v as string[]) || [];
        return (
          <div className="flex flex-wrap gap-1">
            {list.map((r) => (
              <Badge key={r} size="sm" style={getRoleBadgeStyle(r)}>{r}</Badge>
            ))}
          </div>
        );
      },
    },
    { key: 'userSttsCd', label: '상태', width: '70px', sortable: true,
      render: (v) => {
        const s = v as string;
        return <Badge intent={getUserAccountStatusIntent(s)} size="sm">{getUserAccountStatusLabel(s, tc, lang)}</Badge>;
      },
    },
    { key: 'failCnt', label: '실패', width: '50px', align: 'center',
      render: (v) => <span className={`text-[10px] ${(v as number) > 0 ? 'text-heading' : 'text-hint'}`}>{v as number}</span> },
    { key: 'authProvider', label: '인증', width: '70px',
      render: (v) => <span className="text-muted-foreground text-[10px]">{v as string}</span> },
    { key: 'lastLoginDtm', label: '최종 로그인', width: '140px', sortable: true,
      render: (v) => (
        <span className="text-muted-foreground font-mono text-[10px]">
          {formatDateTime(v as string)}
        </span>
      ),
    },
    { key: 'userId', label: '관리', width: '90px', align: 'center', sortable: false,
      render: (_v, row) => (
        <div className="flex items-center justify-center gap-1">
          <button type="button" onClick={() => setAssignTarget(row)}
                  className="p-1 text-hint hover:text-heading" title="역할 배정">
            <UserCog className="w-3 h-3" />
          </button>
          {row.userSttsCd === 'LOCKED' && (
            <button type="button" onClick={() => handleUnlock(row.userId, row.userAcnt)}
                    className="p-1 text-hint hover:text-label" title="잠금 해제">
              <Key className="w-3 h-3" />
            </button>
          )}
        </div>
      ),
    },
  ], []);

  // ── 감사 로그 컬럼 ──────────────
  const auditColumns: DataColumn<ApiAuditLog & Record<string, unknown>>[] = useMemo(() => [
    { key: 'createdAt', label: '일시', width: '160px', sortable: true,
      render: (v) => <span className="text-muted-foreground font-mono text-[10px]">{formatDateTime(v as string)}</span> },
    { key: 'userAcnt', label: '사용자', width: '90px', sortable: true,
      render: (v) => <span className="text-label font-mono">{(v as string) || '-'}</span> },
    { key: 'actionCd', label: '액션', width: '180px', sortable: true,
      render: (v) => <span className="text-heading font-medium">{v as string}</span> },
    { key: 'resourceType', label: '리소스', width: '110px',
      render: (v) => <span className="text-muted-foreground">{(v as string) || '-'}</span> },
    { key: 'ipAddress', label: 'IP', width: '120px',
      render: (v) => <span className="text-hint font-mono text-[10px]">{(v as string) || '-'}</span> },
    { key: 'result', label: '결과', width: '70px', sortable: true,
      render: (v) => {
        const r = v as string;
        return <Badge intent={r === 'SUCCESS' ? 'success' : 'critical'} size="xs">{r || '-'}</Badge>;
      },
    },
    { key: 'failReason', label: '실패 사유',
      render: (v) => <span className="text-heading text-[10px]">{(v as string) || '-'}</span> },
  ], []);

  return (
    <PageContainer size="lg">
      <PageHeader
        icon={Shield}
        iconColor="text-label"
        title={t('accessControl.title')}
        description={t('accessControl.desc')}
        actions={
          <>
            {userStats && (
              <div className="flex items-center gap-2 text-[10px] text-hint">
                <UserCheck className="w-3.5 h-3.5 text-label" />
                활성 <span className="text-label font-bold">{userStats.active}</span>명
                <span className="mx-1">|</span>
                잠금 <span className="text-heading font-bold">{userStats.locked}</span>
                <span className="mx-1">|</span>
                총 <span className="text-heading font-bold">{userStats.total}</span>
              </div>
            )}
            <Button
              variant="ghost"
              size="sm"
              onClick={() => { if (tab === 'users') loadUsers(); else if (tab === 'audit') loadAudit(); }}
              title="새로고침"
              icon={<RefreshCw className="w-3.5 h-3.5" />}
            >
              <span className="sr-only">새로고침</span>
            </Button>
          </>
        }
      />

      {/* 탭 */}
      <div className="flex gap-1">
        {([
          { key: 'roles', icon: Shield, label: '역할 관리' },
          { key: 'users', icon: Users, label: '사용자 관리' },
          { key: 'audit', icon: FileText, label: '감사 로그' },
          { key: 'policy', icon: Lock, label: '보안 정책' },
        ] as const).map((tt) => (
          <button
            key={tt.key}
            type="button"
            onClick={() => setTab(tt.key)}
            className={`flex items-center gap-1.5 px-4 py-2 rounded-lg text-xs transition-colors ${
              tab === tt.key ? 'bg-blue-600 text-on-vivid' : 'text-muted-foreground hover:bg-secondary hover:text-foreground'
            }`}
          >
            <tt.icon className="w-3.5 h-3.5" />
            {tt.label}
          </button>
        ))}
      </div>

      {error && <div className="text-xs text-heading">에러: {error}</div>}

      {/* ── 역할 관리 (PermissionsPanel: 트리 + R/C/U/D 매트릭스) ── */}
      {tab === 'roles' && <PermissionsPanel />}

      {/* ── 사용자 관리 ── */}
      {tab === 'users' && (
        <>
          {/* 통계 카드 */}
          {userStats && (
            <div className="grid grid-cols-4 gap-3">
              <StatCard label="총 사용자" value={userStats.total} color="text-heading" />
              <StatCard label="활성" value={userStats.active} color="text-label" />
              <StatCard label="잠금" value={userStats.locked} color="text-heading" />
              <StatCard label="비활성" value={userStats.inactive} color="text-gray-400" />
            </div>
          )}

          {usersLoading && <div className="flex items-center justify-center py-12 text-muted-foreground"><Loader2 className="w-5 h-5 animate-spin" /></div>}
          {!usersLoading && (
            <DataTable
              data={users as (AdminUser & Record<string, unknown>)[]}
              columns={userColumns}
              pageSize={10}
              searchPlaceholder="계정, 이름, 이메일 검색..."
              searchKeys={['userAcnt', 'userNm', 'email', 'rnkpNm']}
              exportFilename="사용자목록"
              exportResource="admin:user-management"
              showPagination
            />
          )}
        </>
      )}

      {/* ── 감사 로그 ── */}
      {tab === 'audit' && (
        <>
          {/* 통계 카드 */}
          {auditStats && (
            <div className="grid grid-cols-4 gap-3">
              <StatCard label="전체 로그" value={auditStats.total} color="text-heading" />
              <StatCard label="24시간" value={auditStats.last24h} color="text-label" />
              <StatCard label="실패 (24시간)" value={auditStats.failed24h} color="text-heading" />
              <StatCard label="액션 종류" value={auditStats.byAction.length} color="text-heading" />
            </div>
          )}

          {/* 액션별 분포 */}
          {auditStats && auditStats.byAction.length > 0 && (
            <Card>
              <CardHeader className="px-4 pt-3 pb-2"><CardTitle className="text-xs text-label">액션별 분포 (7일)</CardTitle></CardHeader>
              <CardContent className="px-4 pb-4">
                <div className="flex flex-wrap gap-2">
                  {auditStats.byAction.map((a) => (
                    <Badge key={a.action} className="bg-surface-overlay text-muted-foreground border border-border text-[10px]">
                      {a.action} <span className="text-label font-bold ml-1">{a.count}</span>
                    </Badge>
                  ))}
                </div>
              </CardContent>
            </Card>
          )}

          {auditLoading && <div className="flex items-center justify-center py-12 text-muted-foreground"><Loader2 className="w-5 h-5 animate-spin" /></div>}
          {!auditLoading && (
            <DataTable
              data={auditLogs as (ApiAuditLog & Record<string, unknown>)[]}
              columns={auditColumns}
              pageSize={20}
              searchPlaceholder="사용자, 액션, IP 검색..."
              searchKeys={['userAcnt', 'actionCd', 'resourceType', 'ipAddress']}
              exportFilename="감사로그"
              exportResource="admin:audit-logs"
              title="모든 운영자 의사결정 자동 기록 (audit_log)"
              showPagination
            />
          )}
        </>
      )}

      {/* 역할 배정 다이얼로그 */}
      {assignTarget && (
        <UserRoleAssignDialog
          user={assignTarget}
          onClose={() => setAssignTarget(null)}
          onSaved={loadUsers}
        />
      )}

      {/* ── 보안 정책 ── */}
      {tab === 'policy' && (
        <div className="grid grid-cols-2 gap-3">
          <PolicyCard title="비밀번호 정책" rows={[
            ['최소 길이', '9자 이상'],
            ['복잡도', '영문+숫자+특수문자 조합'],
            ['변경 주기', '90일'],
            ['재사용 제한', '최근 3회'],
            ['만료 경고', '14일 전'],
          ]} />
          <PolicyCard title="계정 잠금 정책" rows={[
            ['잠금 임계', '5회 연속 실패'],
            ['잠금 시간', '관리자 해제 시까지'],
            ['실패 카운터 증가', 'PasswordAuthProvider'],
            ['관리자 해제', 'POST /api/admin/users/{id}/unlock'],
            ['감사 기록', 'auth_login_hist + auth_audit_log'],
          ]} />
          <PolicyCard title="세션 관리" rows={[
            ['세션 타임아웃', '30분 (미사용 시)'],
            ['JWT 만료', '24시간'],
            ['저장 방식', 'HttpOnly Cookie'],
            ['세션 갱신', '활동 시 자동 연장'],
          ]} />
          <PolicyCard title="감사 로그 정책" rows={[
            ['감사 대상', '모든 @Auditable 액션 + 로그인'],
            ['기록 위치', 'kcg.auth_audit_log'],
            ['접근 로그', 'kcg.auth_access_log (비동기)'],
            ['로그인 이력', 'kcg.auth_login_hist'],
            ['조회 권한', 'admin:audit-logs (READ)'],
          ]} />
        </div>
      )}
    </PageContainer>
  );
}

function StatCard({ label, value, color }: { label: string; value: number; color: string }) {
  return (
    <Card>
      <CardContent className="p-4">
        <div className="text-[10px] text-hint">{label}</div>
        <div className={`text-2xl font-bold ${color} mt-1`}>{value.toLocaleString()}</div>
      </CardContent>
    </Card>
  );
}

function PolicyCard({ title, rows }: { title: string; rows: [string, string][] }) {
  return (
    <Card>
      <CardHeader className="px-4 pt-3 pb-2"><CardTitle className="text-xs text-label">{title}</CardTitle></CardHeader>
      <CardContent className="px-4 pb-4 space-y-2">
        {rows.map(([k, v]) => (
          <div key={k} className="flex justify-between text-[11px]">
            <span className="text-hint">{k}</span>
            <span className="text-label font-medium">{v}</span>
          </div>
        ))}
      </CardContent>
    </Card>
  );
}
