'use client'

import { useState, useTransition } from 'react'
import { useToast } from '@/hooks/use-toast'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Switch } from '@/components/ui/switch'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { 
  Save, 
  Edit3, 
  X, 
  Check, 
  Lock, 
  Shield, 
  Clock, 
  Smartphone,
  RotateCcw,
  AlertTriangle
} from 'lucide-react'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/alert-dialog'
import { resetSecuritySettings, updateSecuritySettings } from '@/lib/password-policy/service'

export interface SecuritySettings {
  id: number
  // 패스워드 정책
  minPasswordLength: number
  requireUppercase: boolean
  requireLowercase: boolean
  requireNumbers: boolean
  requireSymbols: boolean
  passwordExpiryDays: number | null
  passwordHistoryCount: number
  // 계정 잠금 정책
  maxFailedAttempts: number
  lockoutDurationMinutes: number
  // MFA 정책
  requireMfaForPartners: boolean
  smsTokenExpiryMinutes: number
  maxSmsAttemptsPerDay: number
  // 세션 관리
  sessionTimeoutMinutes: number
  // 메타데이터
  createdAt: Date
  updatedAt: Date
}

interface Props {
  initialSettings: SecuritySettings
}

interface SettingItem {
  key: keyof SecuritySettings
  label: string
  description: string
  type: 'number' | 'boolean' | 'nullable-number'
  min?: number
  max?: number
  unit?: string
}

const settingCategories = [
  {
    title: '패스워드 정책',
    description: '사용자 비밀번호 요구사항을 설정합니다',
    icon: Lock,
    items: [
      {
        key: 'minPasswordLength' as const,
        label: '최소 길이',
        description: '비밀번호 최소 문자 수',
        type: 'number' as const,
        min: 4,
        max: 128,
        unit: '자'
      },
      {
        key: 'requireUppercase' as const,
        label: '대문자 필수',
        description: '대문자 포함 필수 여부',
        type: 'boolean' as const
      },
      {
        key: 'requireLowercase' as const,
        label: '소문자 필수',
        description: '소문자 포함 필수 여부',
        type: 'boolean' as const
      },
      {
        key: 'requireNumbers' as const,
        label: '숫자 필수',
        description: '숫자 포함 필수 여부',
        type: 'boolean' as const
      },
      {
        key: 'requireSymbols' as const,
        label: '특수문자 필수',
        description: '특수문자 포함 필수 여부',
        type: 'boolean' as const
      },
      {
        key: 'passwordExpiryDays' as const,
        label: '만료 기간',
        description: '비밀번호 만료일 (0이면 만료 없음)',
        type: 'nullable-number' as const,
        min: 0,
        max: 365,
        unit: '일'
      },
      {
        key: 'passwordHistoryCount' as const,
        label: '히스토리 개수',
        description: '중복 방지할 이전 비밀번호 개수',
        type: 'number' as const,
        min: 0,
        max: 20,
        unit: '개'
      }
    ]
  },
  {
    title: '계정 잠금 정책',
    description: '로그인 실패 시 계정 잠금 설정',
    icon: Shield,
    items: [
      {
        key: 'maxFailedAttempts' as const,
        label: '최대 실패 횟수',
        description: '계정 잠금까지 허용되는 로그인 실패 횟수',
        type: 'number' as const,
        min: 1,
        max: 20,
        unit: '회'
      },
      {
        key: 'lockoutDurationMinutes' as const,
        label: '잠금 시간',
        description: '계정 잠금 지속 시간',
        type: 'number' as const,
        min: 1,
        max: 1440,
        unit: '분'
      }
    ]
  },
  {
    title: 'MFA 정책',
    description: '다단계 인증 설정',
    icon: Smartphone,
    items: [
      {
        key: 'requireMfaForPartners' as const,
        label: '협력업체 MFA 필수',
        description: '협력업체 사용자 MFA 인증 필수 여부',
        type: 'boolean' as const
      },
      {
        key: 'smsTokenExpiryMinutes' as const,
        label: 'SMS 토큰 만료',
        description: 'SMS 인증 토큰 만료 시간',
        type: 'number' as const,
        min: 1,
        max: 30,
        unit: '분'
      },
      {
        key: 'maxSmsAttemptsPerDay' as const,
        label: '일일 SMS 한도',
        description: '일일 SMS 전송 최대 횟수',
        type: 'number' as const,
        min: 1,
        max: 100,
        unit: '회'
      }
    ]
  },
  {
    title: '세션 관리',
    description: '사용자 세션 설정',
    icon: Clock,
    items: [
      {
        key: 'sessionTimeoutMinutes' as const,
        label: '세션 타임아웃',
        description: '비활성 상태에서 자동 로그아웃까지의 시간',
        type: 'number' as const,
        min: 5,
        max: 1440,
        unit: '분'
      }
    ]
  }
]

export default function SecuritySettingsTable({ initialSettings }: Props) {
  const [settings, setSettings] = useState<SecuritySettings>(initialSettings)
  const [editingItems, setEditingItems] = useState<Set<string>>(new Set())
  const [tempValues, setTempValues] = useState<Record<string, any>>({})
  const [isPending, startTransition] = useTransition()
  const { toast } = useToast()

  const handleEdit = (key: string) => {
    setEditingItems(prev => new Set([...prev, key]))
    setTempValues(prev => ({ ...prev, [key]: settings[key as keyof SecuritySettings] }))
  }

  const handleCancel = (key: string) => {
    setEditingItems(prev => {
      const newSet = new Set(prev)
      newSet.delete(key)
      return newSet
    })
    setTempValues(prev => {
      const newValues = { ...prev }
      delete newValues[key]
      return newValues
    })
  }

  const handleSave = async (key: string) => {
    const value = tempValues[key]
    const item = settingCategories
      .flatMap(cat => cat.items)
      .find(item => item.key === key)
    
    // 클라이언트 사이드 유효성 검사
    if (item && item.type === 'number') {
      if (value < (item.min || 0) || value > (item.max || Infinity)) {
        toast({
          title: '유효하지 않은 값',
          description: `${item.label}은(는) ${item.min || 0}${item.unit || ''} 이상 ${item.max || Infinity}${item.unit || ''} 이하여야 합니다.`,
          variant: 'destructive',
        })
        return
      }
    }
    
    startTransition(async () => {
      try {
        const result = await updateSecuritySettings({
          [key]: value
        })

        if (result.success) {
          setSettings(prev => ({ ...prev, [key]: value, updatedAt: new Date() }))
          setEditingItems(prev => {
            const newSet = new Set(prev)
            newSet.delete(key)
            return newSet
          })
          setTempValues(prev => {
            const newValues = { ...prev }
            delete newValues[key]
            return newValues
          })
          toast({
            title: '설정 저장됨',
            description: `${item?.label || '설정'}이(가) 성공적으로 업데이트되었습니다.`,
          })
        } else {
          toast({
            title: '저장 실패',
            description: result.error || '설정 저장 중 오류가 발생했습니다.',
            variant: 'destructive',
          })
        }
      } catch (error) {
        toast({
          title: '저장 실패',
          description: '설정 저장 중 오류가 발생했습니다.',
          variant: 'destructive',
        })
      }
    })
  }

  const handleValueChange = (key: string, value: any) => {
    setTempValues(prev => ({ ...prev, [key]: value }))
  }

  const handleReset = async () => {
    startTransition(async () => {
      try {
        const result = await resetSecuritySettings()

        if (result.success) {
          // 페이지 새로고침으로 최신 데이터 로드
          window.location.reload()
        } else {
          toast({
            title: '초기화 실패',
            description: result.error || '설정 초기화 중 오류가 발생했습니다.',
            variant: 'destructive',
          })
        }
      } catch (error) {
        toast({
          title: '초기화 실패',
          description: '설정 초기화 중 오류가 발생했습니다.',
          variant: 'destructive',
        })
      }
    })
  }

  const renderValue = (item: SettingItem) => {
    const key = item.key
    const isEditing = editingItems.has(key)
    const currentValue = isEditing ? tempValues[key] : settings[key]

    if (isEditing) {
      if (item.type === 'boolean') {
        return (
          <div className="flex items-center space-x-2">
            <Switch
              checked={currentValue}
              onCheckedChange={(checked) => handleValueChange(key, checked)}
            />
            <span className="text-sm">{currentValue ? '사용' : '사용 안함'}</span>
          </div>
        )
      } else {
      // nullable-number 타입을 위한 특별 처리
      if (item.type === 'nullable-number') {
        return (
          <Input
            type="number"
            value={currentValue === null ? '' : currentValue}
            onChange={(e) => {
              const value = e.target.value === '' ? null : parseInt(e.target.value)
              handleValueChange(key, value)
            }}
            min={item.min}
            max={item.max}
            className="w-24"
            placeholder="0 (만료없음)"
          />
        )
      } else {
        return (
          <Input
            type="number"
            value={currentValue || ''}
            onChange={(e) => {
              const value = e.target.value === '' ? 0 : parseInt(e.target.value)
              handleValueChange(key, value)
            }}
            min={item.min}
            max={item.max}
            className="w-24"
          />
        )
      }
    }
    }

    // 읽기 모드
    if (item.type === 'boolean') {
      return (
        <Badge variant={currentValue ? 'default' : 'secondary'}>
          {currentValue ? '사용' : '사용 안함'}
        </Badge>
      )
    } else {
      let displayValue: string
      
      if (item.type === 'nullable-number') {
        if (currentValue === null || currentValue === 0) {
          displayValue = item.key === 'passwordExpiryDays' ? '만료 없음' : '사용 안함'
        } else {
          displayValue = `${currentValue}${item.unit || ''}`
        }
      } else {
        displayValue = `${currentValue || 0}${item.unit || ''}`
      }
      
      return (
        <span className="font-medium">{displayValue}</span>
      )
    }
  }

  const renderActions = (key: string) => {
    const isEditing = editingItems.has(key)

    if (isEditing) {
      return (
        <div className="flex items-center space-x-1">
          <Button
            size="sm"
            variant="ghost"
            onClick={() => handleSave(key)}
            disabled={isPending}
          >
            <Check className="h-4 w-4" />
          </Button>
          <Button
            size="sm"
            variant="ghost"
            onClick={() => handleCancel(key)}
            disabled={isPending}
          >
            <X className="h-4 w-4" />
          </Button>
        </div>
      )
    }

    return (
      <Button
        size="sm"
        variant="ghost"
        onClick={() => handleEdit(key)}
        disabled={isPending}
      >
        <Edit3 className="h-4 w-4" />
      </Button>
    )
  }

  return (
    <div className="space-y-6">
      {/* 액션 헤더 */}
      <div className="flex justify-between items-center">
        <div>
          <p className="text-sm text-muted-foreground">
            각 항목을 클릭하여 수정할 수 있습니다.
          </p>
        </div>
        <AlertDialog>
          <AlertDialogTrigger asChild>
            <Button variant="outline" size="sm" disabled={isPending}>
              <RotateCcw className="h-4 w-4 mr-2" />
              기본값으로 초기화
            </Button>
          </AlertDialogTrigger>
          <AlertDialogContent>
            <AlertDialogHeader>
              <AlertDialogTitle className="flex items-center space-x-2">
                <AlertTriangle className="h-5 w-5 text-orange-500" />
                <span>설정 초기화 확인</span>
              </AlertDialogTitle>
              <AlertDialogDescription>
                모든 보안 설정을 기본값으로 초기화하시겠습니까? 
                <br />
                <strong>이 작업은 되돌릴 수 없습니다.</strong>
              </AlertDialogDescription>
            </AlertDialogHeader>
            <AlertDialogFooter>
              <AlertDialogCancel>취소</AlertDialogCancel>
              <AlertDialogAction onClick={handleReset} disabled={isPending}>
                초기화
              </AlertDialogAction>
            </AlertDialogFooter>
          </AlertDialogContent>
        </AlertDialog>
      </div>
    
      {settingCategories.map((category) => (
        <Card key={category.title}>
          <CardHeader>
            <CardTitle className="flex items-center space-x-2">
              <category.icon className="h-5 w-5" />
              <span>{category.title}</span>
            </CardTitle>
            <CardDescription>{category.description}</CardDescription>
          </CardHeader>
          <CardContent>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-[200px]">설정 항목</TableHead>
                  <TableHead>설명</TableHead>
                  <TableHead className="w-[150px]">현재 값</TableHead>
                  <TableHead className="w-[100px]">작업</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {category.items.map((item) => (
                  <TableRow key={item.key}>
                    <TableCell className="font-medium">{item.label}</TableCell>
                    <TableCell className="text-muted-foreground">
                      {item.description}
                    </TableCell>
                    <TableCell>{renderValue(item)}</TableCell>
                    <TableCell>{renderActions(item.key)}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </CardContent>
        </Card>
      ))}
      
      <div className="flex justify-between items-center text-xs text-muted-foreground">
        <span>마지막 업데이트: {settings.updatedAt.toLocaleString('ko-KR')}</span>
        {editingItems.size > 0 && (
          <Badge variant="secondary">
            {editingItems.size}개 항목 편집 중
          </Badge>
        )}
      </div>
    </div>
  )
}