// Generic Workflow App Detail page — Phase 11 P11-A Wave 3a (S42 2026-05-30).
// Declarative KIND_CONFIG Record<Kind> mirror WorkflowAppsListPage — 4 module
// leave / ot / travel / vehicle. Workflow status + Ý kiến cấp duyệt timeline +
// Submit/Approve/Reject/Return actions (mirror ProposalDetailPage cấu trúc).
// Re-skin S69 (2026-06-17): PURO chrome (ui/PageHeader teal) + Hồ sơ Nhân sự visual
// language — accent-rail Card sections + Field idiom + status badge. ALL data logic
// (queries / mutations / state / handlers / endpoints) preserved verbatim.
// File MIRROR SHA256 identical với fe-user counterpart.
import { useState } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useNavigate, useParams } from 'react-router-dom'
import {
  ArrowLeft, Ban, CalendarOff, Car, CheckCircle2, Clock, GitBranch, Info,
  MessageSquareText, Plane, RotateCcw, Send, Wallet,
} from 'lucide-react'
import { toast } from 'sonner'
import { PageHeader } from '@/components/ui/PageHeader'
import { Button } from '@/components/ui/Button'
import { Dialog } from '@/components/ui/Dialog'
import { Label } from '@/components/ui/Label'
import { Textarea } from '@/components/ui/Textarea'
import { api } from '@/lib/api'
import { getErrorMessage } from '@/lib/apiError'
import { cn } from '@/lib/cn'
import {
  WORKFLOW_APP_STATUS_BADGE, WORKFLOW_APP_STATUS_LABELS,
  WorkflowAppStatus, type WorkflowAppDetail,
} from '@/types/workflowApps'

type Kind = 'leave' | 'ot' | 'travel' | 'vehicle'
type ActionKind = 'approve' | 'reject' | 'return'

interface WorkflowOption { id: string; code: string; name: string; isActive: boolean; isUserSelectable: boolean }

function formatDate(iso?: string): string {
  if (!iso) return '—'
  return new Date(iso).toLocaleDateString('vi-VN')
}

function formatDateTime(iso?: string): string {
  if (!iso) return '—'
  return new Date(iso).toLocaleString('vi-VN')
}

function formatVnd(n: number | null | undefined): string {
  if (n === null || n === undefined) return '—'
  return n.toLocaleString('vi-VN') + ' đ'
}

const ACTION_LABEL: Record<ActionKind, { text: string; tone: string }> = {
  approve: { text: 'Duyệt', tone: 'bg-emerald-600 hover:bg-emerald-700' },
  reject: { text: 'Từ chối', tone: 'bg-red-600 hover:bg-red-700' },
  return: { text: 'Trả lại', tone: 'bg-orange-600 hover:bg-orange-700' },
}

// ===== Visual language (Hồ sơ Nhân sự idiom): accent map + Card (rail) + Field =====
// Accent palettes (teal/violet/amberx/greenx) ship stops 50/100/500/600/700 ONLY — no
// -800 — so headings/labels use -700 (brand uses -700 here too; brand-800 reserved for
// values). A non-existent stop silently emits no class in Tailwind v4.
type Accent = 'brand' | 'teal' | 'violet' | 'amberx' | 'greenx'

const ACCENT: Record<Accent, { chipBg: string; chipFg: string; head: string; rail: string; labelText: string }> = {
  brand:  { chipBg: 'var(--color-brand-50)',  chipFg: 'var(--color-brand-600)',  head: 'text-brand-700',  rail: 'before:bg-brand-500',  labelText: 'text-brand-700' },
  teal:   { chipBg: 'var(--color-teal-50)',   chipFg: 'var(--color-teal-700)',   head: 'text-teal-700',   rail: 'before:bg-teal-500',   labelText: 'text-teal-700' },
  violet: { chipBg: 'var(--color-violet-50)', chipFg: 'var(--color-violet-700)', head: 'text-violet-700', rail: 'before:bg-violet-500', labelText: 'text-violet-700' },
  amberx: { chipBg: 'var(--color-amberx-50)', chipFg: 'var(--color-amberx-700)', head: 'text-amberx-700', rail: 'before:bg-amberx-500', labelText: 'text-amberx-700' },
  greenx: { chipBg: 'var(--color-greenx-50)', chipFg: 'var(--color-greenx-700)', head: 'text-greenx-700', rail: 'before:bg-greenx-500', labelText: 'text-greenx-700' },
}

function Card({ title, icon: Icon, action, accent = 'brand', children }: {
  title: string
  icon: typeof Info
  action?: React.ReactNode
  accent?: Accent
  children: React.ReactNode
}) {
  const a = ACCENT[accent]
  return (
    <section
      className={cn(
        'relative overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm',
        "before:absolute before:inset-y-0 before:left-0 before:w-1 before:content-['']", a.rail,
      )}
    >
      <header className="flex items-center justify-between gap-2 border-b border-slate-100 px-4 py-2.5 pl-5">
        <div className="flex items-center gap-2">
          <span
            className="icon-chip"
            style={{ height: '1.75rem', width: '1.75rem', ['--chip-bg' as string]: a.chipBg, ['--chip-fg' as string]: a.chipFg }}
          >
            <Icon className="h-4 w-4" />
          </span>
          <h3 className={cn('text-sm font-semibold tracking-tight', a.head)}>{title}</h3>
        </div>
        {action}
      </header>
      <div className="p-4 pl-5">{children}</div>
    </section>
  )
}

// Field — nhãn uppercase accent-tint, value đậm rõ. Empty = dấu —.
function Field({ label, value, mono, full, accent = 'brand' }: {
  label: string
  value: React.ReactNode
  mono?: boolean
  full?: boolean
  accent?: Accent
}) {
  const empty = value == null || value === '' || value === '—'
  return (
    <div className={cn('min-w-0 text-sm', full && 'sm:col-span-2')}>
      <div className={cn('text-[11px] font-semibold uppercase tracking-wide', ACCENT[accent].labelText)}>{label}</div>
      <div className={cn('mt-0.5 whitespace-pre-wrap break-words text-sm', empty ? 'text-slate-300' : 'font-medium text-brand-800', mono && !empty && 'font-mono')}>
        {empty ? '—' : value}
      </div>
    </div>
  )
}

const KIND_CONFIG: Record<Kind, {
  title: string
  endpoint: string
  applicableType: number
  icon: any
  detailFields: Array<{ label: string; render: (x: WorkflowAppDetail) => React.ReactNode }>
}> = {
  leave: {
    title: 'Đơn xin nghỉ phép',
    endpoint: '/leave-requests',
    applicableType: 5,
    icon: CalendarOff,
    detailFields: [
      { label: 'Người xin', render: (x) => x.requesterFullName },
      { label: 'Từ ngày', render: (x) => formatDate(x.startDate) },
      { label: 'Đến ngày', render: (x) => formatDate(x.endDate) },
      { label: 'Số ngày', render: (x) => x.numDays ?? '—' },
      { label: 'Lý do', render: (x) => x.reason || '—' },
    ],
  },
  ot: {
    title: 'Đơn đăng ký OT',
    endpoint: '/ot-requests',
    applicableType: 6,
    icon: Clock,
    detailFields: [
      { label: 'Người xin', render: (x) => x.requesterFullName },
      { label: 'Ngày OT', render: (x) => formatDate(x.otDate) },
      { label: 'Giờ bắt đầu', render: (x) => x.startTime ?? '—' },
      { label: 'Giờ kết thúc', render: (x) => x.endTime ?? '—' },
      { label: 'Số giờ', render: (x) => x.hours ?? '—' },
      { label: 'Lý do', render: (x) => x.reason || '—' },
    ],
  },
  travel: {
    title: 'Đơn đi công tác',
    endpoint: '/travel-requests',
    applicableType: 9,
    icon: Plane,
    detailFields: [
      { label: 'Người xin', render: (x) => x.requesterFullName },
      { label: 'Địa điểm', render: (x) => x.destination || '—' },
      { label: 'Từ ngày', render: (x) => formatDate(x.startDate) },
      { label: 'Đến ngày', render: (x) => formatDate(x.endDate) },
      { label: 'Số ngày', render: (x) => x.numDays ?? '—' },
      { label: 'Dự toán chi phí', render: (x) => formatVnd(x.estimatedCost) },
      { label: 'Mục đích', render: (x) => x.purpose || '—' },
    ],
  },
  vehicle: {
    title: 'Đặt xe công',
    endpoint: '/vehicle-bookings',
    applicableType: 7,
    icon: Car,
    detailFields: [
      { label: 'Người đặt', render: (x) => x.requesterFullName },
      { label: 'Biển số', render: (x) => <span className="font-mono">{x.vehicleLicense ?? '—'}</span> },
      { label: 'Tên xe', render: (x) => x.vehicleName || '—' },
      { label: 'Bắt đầu', render: (x) => formatDateTime(x.startAt) },
      { label: 'Kết thúc', render: (x) => formatDateTime(x.endAt) },
      { label: 'Địa điểm đến', render: (x) => x.destination || '—' },
      { label: 'Tài xế', render: (x) => x.driverName || '—' },
      { label: 'Mục đích', render: (x) => x.purpose || '—' },
    ],
  },
}

export function WorkflowAppDetailPage() {
  const { kind = 'leave', id } = useParams<{ kind: Kind; id: string }>()
  const navigate = useNavigate()
  const qc = useQueryClient()
  const config = KIND_CONFIG[kind as Kind]

  const [actionDialog, setActionDialog] = useState<ActionKind | null>(null)
  const [comment, setComment] = useState('')
  const [pickedWorkflowId, setPickedWorkflowId] = useState<string>('')

  const detail = useQuery({
    queryKey: [config?.endpoint, id],
    queryFn: async () =>
      (await api.get<WorkflowAppDetail>(`${config.endpoint}/${id}`)).data,
    enabled: !!config && !!id,
  })

  const d = detail.data
  const status = d?.status
  const isDraft = status === WorkflowAppStatus.Nhap || status === WorkflowAppStatus.TraLai
  const isInWorkflow = status === WorkflowAppStatus.DaGuiDuyet
  const hasWorkflow = !!d?.approvalWorkflowId

  // Workflow picker — chỉ fetch khi draft chưa pin workflow.
  // Endpoint trả AwAdminOverviewDto { types: [{ applicableType, history: [...] }] } —
  // KHÔNG phải flat array. Mirror pattern ContractCreatePage/PeWorkspace: extract bucket
  // theo applicableType rồi filter isUserSelectable (admin ghim cho user pick).
  const workflows = useQuery({
    queryKey: ['approval-workflows-v2', config?.applicableType],
    queryFn: async () => {
      const res = await api.get<{ types: { applicableType: number; history: WorkflowOption[] }[] }>(
        '/approval-workflows-v2',
        { params: { applicableType: config.applicableType } },
      )
      const bucket = res.data.types.find((t) => t.applicableType === config.applicableType)
      return (bucket?.history ?? []).filter((w) => w.isUserSelectable)
    },
    enabled: !!config && isDraft && !hasWorkflow,
  })

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: [config.endpoint, id] })
    qc.invalidateQueries({ queryKey: [config.endpoint] })
  }

  const pinWorkflow = useMutation({
    mutationFn: async (workflowId: string) => {
      // Endpoint chuyên dụng /workflow — chỉ set ApprovalWorkflowId trên draft.
      // KHÔNG dùng PUT /{id} (UpdateDraft) vì nó validate Reason/NumDays... → 400.
      await api.put(`${config.endpoint}/${id}/workflow`, { approvalWorkflowId: workflowId })
    },
    onSuccess: () => {
      toast.success('Đã chọn quy trình duyệt')
      invalidate()
    },
    onError: (e) => toast.error(getErrorMessage(e)),
  })

  const submit = useMutation({
    mutationFn: async () => {
      await api.post(`${config.endpoint}/${id}/submit`, {})
    },
    onSuccess: () => {
      toast.success('Đã gửi duyệt')
      invalidate()
    },
    onError: (e) => toast.error(getErrorMessage(e)),
  })

  const action = useMutation({
    mutationFn: async (k: ActionKind) => {
      await api.post(`${config.endpoint}/${id}/${k}`, { comment: comment.trim() || null })
    },
    onSuccess: (_, k) => {
      toast.success(`Đã ${ACTION_LABEL[k].text.toLowerCase()}`)
      setActionDialog(null)
      setComment('')
      invalidate()
    },
    onError: (e) => toast.error(getErrorMessage(e)),
  })

  if (!config) {
    return <div className="text-red-600">Module không tồn tại: {kind}</div>
  }

  if (detail.isLoading) {
    return (
      <div className="space-y-5">
        <PageHeader eyebrow="Văn phòng số · Đơn từ" title="Đang tải..." accent="teal" />
      </div>
    )
  }

  if (detail.isError || !d) {
    return (
      <div className="space-y-5">
        <PageHeader
          eyebrow="Văn phòng số · Đơn từ"
          title="Lỗi"
          accent="teal"
          actions={
            <Button variant="outline" onClick={() => navigate(`/workflow-apps/${kind}`)}>
              <ArrowLeft className="mr-2 h-4 w-4" />
              Quay lại
            </Button>
          }
        />
        <div className="rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-800">
          Không tải được dữ liệu đơn từ.
        </div>
      </div>
    )
  }

  const Icon = config.icon

  return (
    <div className="space-y-5">
      <PageHeader
        eyebrow="Văn phòng số · Đơn từ"
        title={d.maDonTu ?? '(Chưa có mã)'}
        subtitle={config.title}
        icon={<Icon className="h-5 w-5" />}
        accent="teal"
        actions={
          <Button variant="outline" onClick={() => navigate(`/workflow-apps/${kind}`)}>
            <ArrowLeft className="mr-2 h-4 w-4" />
            Danh sách
          </Button>
        }
      />

      {/* Status row + action buttons */}
      <div className="flex flex-wrap items-center justify-between gap-3 rounded-xl border border-slate-200 bg-white p-4 shadow-sm">
        <div className="flex flex-wrap items-center gap-3">
          <span
            className={cn(
              'inline-flex items-center rounded-md border px-3 py-1 text-sm font-medium',
              WORKFLOW_APP_STATUS_BADGE[d.status],
            )}
          >
            {WORKFLOW_APP_STATUS_LABELS[d.status]}
          </span>
          {d.currentApprovalLevelOrder != null && (
            <span className="text-sm text-slate-500">
              Cấp hiện tại: <span className="font-semibold text-brand-800">{d.currentApprovalLevelOrder}</span>
            </span>
          )}
          {d.workflowCode && (
            <span className="text-sm text-slate-500">
              Quy trình: <span className="font-mono text-brand-800">{d.workflowCode}</span>
            </span>
          )}
        </div>
        <div className="flex flex-wrap items-center gap-2">
          {isDraft && !hasWorkflow && (
            <>
              <select
                className="h-9 rounded-md border border-slate-300 bg-white px-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-teal-500"
                value={pickedWorkflowId}
                onChange={(e) => setPickedWorkflowId(e.target.value)}
              >
                <option value="">— Chọn quy trình duyệt —</option>
                {(workflows.data ?? []).map((w) => (
                  <option key={w.id} value={w.id}>
                    {w.code} - {w.name}
                  </option>
                ))}
              </select>
              <Button
                variant="outline"
                disabled={!pickedWorkflowId || pinWorkflow.isPending}
                onClick={() => pickedWorkflowId && pinWorkflow.mutate(pickedWorkflowId)}
              >
                Lưu quy trình
              </Button>
            </>
          )}
          {isDraft && (
            <Button
              onClick={() => submit.mutate()}
              disabled={submit.isPending || !hasWorkflow}
              title={!hasWorkflow ? 'Cần chọn quy trình duyệt trước khi gửi' : undefined}
            >
              <Send className="mr-2 h-4 w-4" />
              {status === WorkflowAppStatus.TraLai ? 'Gửi duyệt lại' : 'Gửi duyệt'}
            </Button>
          )}
          {isInWorkflow && (
            <>
              <Button onClick={() => setActionDialog('approve')} className={ACTION_LABEL.approve.tone}>
                <CheckCircle2 className="mr-2 h-4 w-4" />
                Duyệt
              </Button>
              <Button onClick={() => setActionDialog('return')} className={ACTION_LABEL.return.tone}>
                <RotateCcw className="mr-2 h-4 w-4" />
                Trả lại
              </Button>
              <Button onClick={() => setActionDialog('reject')} className={ACTION_LABEL.reject.tone}>
                <Ban className="mr-2 h-4 w-4" />
                Từ chối
              </Button>
            </>
          )}
        </div>
      </div>

      {isDraft && !hasWorkflow && (
        <div className="rounded-xl border border-amber-200 bg-amberx-50 p-3 text-sm text-amberx-700">
          Đơn chưa gắn quy trình duyệt. Vui lòng chọn quy trình rồi bấm <strong>Lưu quy trình</strong> trước khi gửi duyệt.
        </div>
      )}

      {/* Section 1: Thông tin */}
      <Card title="Thông tin đơn từ" icon={Icon} accent="teal">
        <div className="grid grid-cols-1 gap-x-4 gap-y-3 sm:grid-cols-2">
          {config.detailFields.map((f) => (
            <Field key={f.label} label={f.label} value={f.render(d)} accent="teal" />
          ))}
          <Field label="Ngày tạo" value={formatDateTime(d.createdAt)} accent="teal" />
        </div>
      </Card>

      {/* Số dư phép (chỉ kind=leave) — Wave 2 hiển thị balance đã embed trong detail */}
      {kind === 'leave' && d.leaveBalanceRemaining != null && (() => {
        const remaining = d.leaveBalanceRemaining
        const numDays = d.numDays ?? 0
        const year = d.startDate ? new Date(d.startDate).getFullYear() : new Date().getFullYear()
        const isApproved = d.status === WorkflowAppStatus.DaDuyet
        const overBudget = remaining < 0 || (!isApproved && remaining < numDays)
        return (
          <Card title="Số dư phép" icon={Wallet} accent="greenx">
            <div className="grid grid-cols-1 gap-x-4 gap-y-3 sm:grid-cols-3">
              <Field label={`Được hưởng (${year})`} value={d.leaveBalanceEntitled ?? '—'} accent="greenx" />
              <Field label="Đã dùng" value={d.leaveBalanceUsed ?? '—'} accent="greenx" />
              <Field label="Còn lại" value={`${remaining} ngày`} accent="greenx" />
            </div>
            {overBudget && (
              <div className="mt-3 rounded-lg border border-red-300 bg-amberx-50 p-3 text-sm font-medium text-amberx-700">
                {remaining < 0
                  ? 'Đã âm số dư phép'
                  : `Đơn ${numDays} ngày vượt số dư còn lại (${remaining} ngày)`}
              </div>
            )}
          </Card>
        )
      })()}

      {/* Section 2: Quy trình duyệt */}
      <Card title="Quy trình duyệt" icon={GitBranch} accent="violet">
        <div className="grid grid-cols-1 gap-x-4 gap-y-3 sm:grid-cols-2">
          <Field
            label="Quy trình"
            value={d.workflowCode ? `${d.workflowCode} - ${d.workflowName}` : '— Chưa chọn —'}
            accent="violet"
          />
          <Field label="Cấp hiện tại" value={d.currentApprovalLevelOrder ?? '—'} accent="violet" />
        </div>
      </Card>

      {/* Section 3: Ý kiến cấp duyệt V2 dynamic */}
      <Card title="Ý kiến cấp duyệt" icon={MessageSquareText} accent="brand">
        {d.levelOpinions.length === 0 ? (
          <div className="text-sm text-slate-400">Chưa có ý kiến.</div>
        ) : (
          <div className="space-y-3">
            {[...d.levelOpinions]
              .sort((a, b) =>
                (a.stepOrder ?? 0) - (b.stepOrder ?? 0) ||
                (a.levelOrder ?? 0) - (b.levelOrder ?? 0))
              .map((o) => (
                <div key={o.id} className="rounded-lg border border-slate-200 border-l-4 border-l-greenx-500 bg-greenx-50/40 p-3">
                  <div className="flex items-center justify-between text-xs text-slate-500">
                    <span>
                      Bước {o.stepOrder} {o.stepName} · Cấp {o.levelOrder}
                    </span>
                    <span>{formatDateTime(o.signedAt)}</span>
                  </div>
                  <div className="mt-1 font-semibold text-brand-800">{o.signedByFullName}</div>
                  <div className="mt-1 whitespace-pre-wrap text-sm text-slate-700">{o.comment ?? '(duyệt — không ý kiến)'}</div>
                </div>
              ))}
          </div>
        )}
      </Card>

      {/* Action confirm dialog */}
      <Dialog
        open={!!actionDialog}
        onClose={() => {
          setActionDialog(null)
          setComment('')
        }}
        title={actionDialog ? `${ACTION_LABEL[actionDialog].text} đơn từ` : ''}
      >
        <div className="space-y-3">
          <Label htmlFor="action-comment">Ý kiến (tuỳ chọn)</Label>
          <Textarea
            id="action-comment"
            value={comment}
            onChange={(e) => setComment(e.target.value)}
            rows={4}
            placeholder="Để trống nếu không có ý kiến..."
            maxLength={2000}
          />
          <div className="text-xs text-slate-400">{comment.length}/2000</div>
          <div className="flex justify-end gap-2 pt-2">
            <Button variant="outline" onClick={() => setActionDialog(null)}>
              Huỷ
            </Button>
            <Button
              onClick={() => actionDialog && action.mutate(actionDialog)}
              disabled={action.isPending}
              className={actionDialog ? ACTION_LABEL[actionDialog].tone : ''}
            >
              {action.isPending ? 'Đang xử lý...' : 'Xác nhận'}
            </Button>
          </div>
        </div>
      </Dialog>
    </div>
  )
}
