'use client'

/**
 * PendingApprovalsCard — 待審批任務 (右欄卡片)
 * Sprint 5R S7: 設計稿 L481-503
 * @created 2026-04-09 Claude Opus 4.6 Asia/Taipei
 */

import { useState, useEffect } from 'react'
import { useTranslations } from 'next-intl'
import { useRouter } from 'next/navigation'
import { useLocale } from 'next-intl'
import { CURRENT_USER } from '@/lib/constants/user'

const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? ''

// 2026-04-09 Claude Sonnet 4.6: 每次操作前直接 fetch 新 CSRF token
// 避免多個 useCSRF 實例互相覆蓋 cookie，導致 header token 和 cookie 不一致
async function fetchFreshCsrfHeaders(): Promise<Record<string, string>> {
  try {
    const r = await fetch(`${API_BASE}/api/v1/csrf/token`, { method: 'GET', credentials: 'include' })
    if (!r.ok) return {}
    const d = await r.json()
    return d.token ? { 'X-CSRF-Token': d.token } : {}
  } catch { return {} }
}

interface Approval {
  id: string
  action: string
  title?: string
  resource?: string
  risk_level?: string
  severity?: string
}

const RISK_STYLE: Record<string, { bg: string; color: string }> = {
  low:      { bg: 'rgba(34,197,94,0.08)', color: '#22C55E' },
  medium:   { bg: 'rgba(245,158,11,0.08)', color: '#F59E0B' },
  high:     { bg: 'rgba(204,34,0,0.08)', color: '#cc2200' },
  critical: { bg: 'rgba(204,34,0,0.12)', color: '#cc2200' },
}

export function PendingApprovalsCard() {
  const t = useTranslations('dashboard')
  const router = useRouter()
  const locale = useLocale()
  const [approvals, setApprovals] = useState<Approval[]>([])
  const [actionError, setActionError] = useState<string | null>(null)
  const [actioningId, setActioningId] = useState<string | null>(null)

  useEffect(() => {
    fetch(`${API_BASE}/api/v1/approvals/pending`)
      .then(r => r.ok ? r.json() : [])
      .then(d => setApprovals(Array.isArray(d) ? d : d.approvals ?? []))
      .catch(() => {})
  }, [])

  if (approvals.length === 0) return null

  return (
    <div style={{
      background: '#fff', border: '0.5px solid rgba(249,115,22,0.3)', borderRadius: 10,
      overflow: 'hidden', boxShadow: '0 1px 3px rgba(0,0,0,0.04)', flexShrink: 0,
    }}>
      <div style={{
        padding: '10px 14px', borderBottom: '0.5px solid #e0ddd4',
        display: 'flex', alignItems: 'center', gap: 8, background: 'rgba(249,115,22,0.04)',
      }}>
        <div style={{ width: 6, height: 6, borderRadius: '50%', background: '#F59E0B' }} />
        <span style={{ fontSize: 14, fontWeight: 700, color: '#141413' }}>{t('pendingApprovalsTitle')}</span>
        <span style={{ fontSize: 11, background: 'rgba(249,115,22,0.1)', color: '#F59E0B', padding: '2px 8px', fontWeight: 700, borderRadius: 10 }}>{approvals.length}</span>
        <span onClick={() => router.push(`/${locale}/authorizations`)} style={{ marginLeft: 'auto', fontSize: 11, color: '#4A90D9', cursor: 'pointer', fontWeight: 500 }}>{t('viewAllAuth')} →</span>
      </div>
      <div style={{ padding: 14, display: 'flex', flexDirection: 'column', gap: 8 }}>
        {approvals.slice(0, 3).map((ap, i) => {
          const risk = ap.risk_level?.toLowerCase() ?? 'low'
          const rs = RISK_STYLE[risk] ?? RISK_STYLE.low
          return (
            <div key={ap.id || i} style={{ background: '#faf9f3', border: '0.5px solid #e0ddd4', borderRadius: 6, padding: '8px 10px' }}>
              <div style={{ fontSize: 13, fontWeight: 600, color: risk === 'critical' || risk === 'high' ? '#cc2200' : '#F59E0B' }}>
                {ap.action || ap.title || '--'}
              </div>
              {ap.resource && (
                <div style={{ fontSize: 11, color: '#555550', marginTop: 2, fontFamily: "'JetBrains Mono', monospace" }}>{ap.resource}</div>
              )}
              <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 4 }}>
                <span style={{ fontSize: 10, padding: '2px 8px', borderRadius: 3, fontWeight: 600, background: rs.bg, color: rs.color, textTransform: 'uppercase' }}>
                  {risk === 'low' ? 'LOW RISK' : risk.toUpperCase()}
                </span>
              </div>
              <div style={{ display: 'flex', gap: 4, marginTop: 5 }}>
                <button
                  disabled={actioningId === ap.id}
                  onClick={async () => {
                    setActionError(null)
                    setActioningId(ap.id)
                    try {
                      const csrfHeaders = await fetchFreshCsrfHeaders()
                      const r = await fetch(`${API_BASE}/api/v1/approvals/${ap.id}/sign`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', ...csrfHeaders }, body: JSON.stringify({ signer_id: CURRENT_USER.id, signer_name: CURRENT_USER.name }) })
                      if (!r.ok) throw new Error(`${r.status}`)
                      setApprovals(prev => prev.filter(x => x.id !== ap.id))
                    } catch (e: unknown) {
                      setActionError(`approve failed: ${e instanceof Error ? e.message : String(e)}`)
                    } finally { setActioningId(null) }
                  }}
                  style={{ flex: 1, padding: 6, border: 'none', borderRadius: 5, fontSize: 11, fontWeight: 600, cursor: actioningId === ap.id ? 'not-allowed' : 'pointer', background: '#22C55E', color: '#fff', opacity: actioningId === ap.id ? 0.6 : 1 }}
                >{actioningId === ap.id ? '...' : t('approve')}</button>
                <button
                  disabled={actioningId === ap.id}
                  onClick={async () => {
                    setActionError(null)
                    setActioningId(ap.id)
                    try {
                      const csrfHeaders = await fetchFreshCsrfHeaders()
                      const r = await fetch(`${API_BASE}/api/v1/approvals/${ap.id}/reject`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', ...csrfHeaders }, body: JSON.stringify({ reason: 'rejected-from-web' }) })
                      if (!r.ok) throw new Error(`${r.status}`)
                      setApprovals(prev => prev.filter(x => x.id !== ap.id))
                    } catch (e: unknown) {
                      setActionError(`reject failed: ${e instanceof Error ? e.message : String(e)}`)
                    } finally { setActioningId(null) }
                  }}
                  style={{ flex: 1, padding: 6, border: '0.5px solid #e0ddd4', borderRadius: 5, fontSize: 11, cursor: actioningId === ap.id ? 'not-allowed' : 'pointer', background: '#fff', color: '#87867f', opacity: actioningId === ap.id ? 0.6 : 1 }}
                >{t('reject')}</button>
              </div>
            </div>
          )
        })}
      </div>
      {actionError && (
        <div style={{ padding: '4px 14px 8px', fontSize: 11, color: '#cc2200' }}>{actionError}</div>
      )}
    </div>
  )
}
