/**
 * #30 PIN 코드 잠금 화면
 *
 * - 4자리 PIN 숫자 패드
 * - PIN 저장: sha256(pin) → SecureStore 'grd_pin_hash' (평문 저장 금지)
 * - 검증: sha256(입력) === 저장 해시
 * - 5회 실패 시 onFail() 호출 (세션 종료)
 *
 * 사용:
 *   <PinLock mode="set"    onSuccess={...} />   // PIN 신규 설정 (2회 확인)
 *   <PinLock mode="verify" onSuccess={...} onFail={...} />  // 잠금 해제
 */
import { useState } from 'react'
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
import * as SecureStore from 'expo-secure-store'
import { sha256 } from '../services/sha256'
import { COLORS } from '../constants/Config'

const PIN_HASH_KEY = 'grd_pin_hash'
const PIN_LENGTH = 4
const MAX_ATTEMPTS = 5

export const PIN_ENABLED_KEY = 'grd_pin_enabled'

export async function isPinSet(): Promise<boolean> {
  const h = await SecureStore.getItemAsync(PIN_HASH_KEY)
  return !!h
}

export async function savePin(pin: string): Promise<void> {
  // 평문 저장 절대 금지 — SHA-256 해시만 저장
  const hash = sha256(pin)
  await SecureStore.setItemAsync(PIN_HASH_KEY, hash)
  await SecureStore.setItemAsync(PIN_ENABLED_KEY, '1')
}

export async function verifyPin(pin: string): Promise<boolean> {
  const stored = await SecureStore.getItemAsync(PIN_HASH_KEY)
  if (!stored) return false
  return sha256(pin) === stored
}

export async function clearPin(): Promise<void> {
  await SecureStore.deleteItemAsync(PIN_HASH_KEY)
  await SecureStore.deleteItemAsync(PIN_ENABLED_KEY)
}

export async function isPinEnabled(): Promise<boolean> {
  const v = await SecureStore.getItemAsync(PIN_ENABLED_KEY)
  return v === '1' && (await isPinSet())
}

type Mode = 'set' | 'verify'

interface Props {
  mode: Mode
  onSuccess: () => void
  onFail?: () => void
  onCancel?: () => void
}

export default function PinLock({ mode, onSuccess, onFail, onCancel }: Props) {
  const [pin, setPin] = useState('')
  const [firstPin, setFirstPin] = useState<string | null>(null) // set 모드 확인용
  const [attempts, setAttempts] = useState(0)
  const [error, setError] = useState('')

  const title =
    mode === 'set'
      ? firstPin == null
        ? 'PIN 설정'
        : 'PIN 재입력'
      : 'PIN 입력'
  const subtitle =
    mode === 'set'
      ? firstPin == null
        ? '4자리 PIN을 설정하세요'
        : '확인을 위해 다시 입력하세요'
      : '잠금을 해제하려면 PIN을 입력하세요'

  const handleDigit = async (d: string) => {
    if (pin.length >= PIN_LENGTH) return
    setError('')
    const next = pin + d
    setPin(next)
    if (next.length === PIN_LENGTH) {
      await submit(next)
    }
  }

  const handleDelete = () => {
    setError('')
    setPin((p) => p.slice(0, -1))
  }

  const submit = async (entered: string) => {
    if (mode === 'set') {
      if (firstPin == null) {
        setFirstPin(entered)
        setPin('')
        return
      }
      if (firstPin === entered) {
        await savePin(entered)
        onSuccess()
      } else {
        setError('PIN이 일치하지 않습니다. 다시 설정하세요.')
        setFirstPin(null)
        setPin('')
      }
      return
    }

    // verify
    const ok = await verifyPin(entered)
    if (ok) {
      setAttempts(0)
      onSuccess()
    } else {
      const a = attempts + 1
      setAttempts(a)
      setPin('')
      if (a >= MAX_ATTEMPTS) {
        setError('5회 실패 — 보안을 위해 로그아웃됩니다.')
        onFail?.()
      } else {
        setError(`PIN이 올바르지 않습니다. (${a}/${MAX_ATTEMPTS})`)
      }
    }
  }

  const keys = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '', '0', 'del']

  return (
    <View style={s.container}>
      <Text style={s.logo}>🛡️</Text>
      <Text style={s.title}>{title}</Text>
      <Text style={s.subtitle}>{subtitle}</Text>

      <View style={s.dots}>
        {Array.from({ length: PIN_LENGTH }).map((_, i) => (
          <View key={i} style={[s.dot, i < pin.length && s.dotFilled]} />
        ))}
      </View>

      {!!error && <Text style={s.error}>{error}</Text>}

      <View style={s.pad}>
        {keys.map((k, i) =>
          k === '' ? (
            <View key={i} style={s.key} />
          ) : k === 'del' ? (
            <TouchableOpacity key={i} style={s.key} onPress={handleDelete}>
              <Text style={s.keyDel}>⌫</Text>
            </TouchableOpacity>
          ) : (
            <TouchableOpacity key={i} style={s.key} onPress={() => handleDigit(k)}>
              <Text style={s.keyText}>{k}</Text>
            </TouchableOpacity>
          )
        )}
      </View>

      {onCancel && (
        <TouchableOpacity onPress={onCancel} style={s.cancel}>
          <Text style={s.cancelText}>취소</Text>
        </TouchableOpacity>
      )}
    </View>
  )
}

const s = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: COLORS.gnbBg,
    alignItems: 'center',
    justifyContent: 'center',
    padding: 28,
  },
  logo: { fontSize: 44, marginBottom: 12 },
  title: { fontSize: 22, fontWeight: '800', color: '#fff', marginBottom: 6 },
  subtitle: { fontSize: 13, color: 'rgba(255,255,255,.6)', marginBottom: 28 },
  dots: { flexDirection: 'row', gap: 18, marginBottom: 18 },
  dot: {
    width: 16, height: 16, borderRadius: 8,
    borderWidth: 2, borderColor: COLORS.accent, backgroundColor: 'transparent',
  },
  dotFilled: { backgroundColor: COLORS.accent },
  error: { color: '#fca5a5', fontSize: 13, marginBottom: 12, textAlign: 'center' },
  pad: { flexDirection: 'row', flexWrap: 'wrap', width: 264, justifyContent: 'space-between' },
  key: {
    width: 78, height: 78, borderRadius: 39,
    alignItems: 'center', justifyContent: 'center', marginVertical: 6,
  },
  keyText: { fontSize: 28, color: '#fff', fontWeight: '600' },
  keyDel: { fontSize: 26, color: 'rgba(255,255,255,.7)' },
  cancel: { marginTop: 24 },
  cancelText: { color: COLORS.accent, fontSize: 15, fontWeight: '600' },
})
