// 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).
// 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, Plane, RotateCcw, Send,
} from 'lucide-react'
import { toast } from 'sonner'
import { PageHeader } from '@/components/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' },
}

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-4">
        <PageHeader title="Đang tải..." />
      </div>
    )
  }

  if (detail.isError || !d) {
    return (
      <div className="space-y-4">
        <PageHeader
          title="Lỗi"
          actions={
            <Button variant="outline" onClick={() => navigate(`/workflow-apps/${kind}`)}>
              <ArrowLeft className="mr-2 h-4 w-4" />
              Quay lại
            </Button>
          }
        />
        <div className="rounded-lg border 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-4">
      <PageHeader
        title={d.maDonTu ?? '(Chưa có mã)'}
        description={config.title}
        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-lg border bg-card p-4">
        <div className="flex 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-muted-foreground">
              Cấp hiện tại: <span className="font-semibold">{d.currentApprovalLevelOrder}</span>
            </span>
          )}
          {d.workflowCode && (
            <span className="text-sm text-muted-foreground">
              Quy trình: <span className="font-mono">{d.workflowCode}</span>
            </span>
          )}
        </div>
        <div className="flex flex-wrap items-center gap-2">
          {isDraft && !hasWorkflow && (
            <>
              <select
                className="h-9 rounded-md border bg-background px-2 text-sm"
                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-lg border bg-amber-50/50 p-3 text-sm text-amber-900">
          Đơ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 */}
      <div className="rounded-lg border bg-card p-6 space-y-3">
        <h3 className="flex items-center gap-2 font-semibold text-base">
          <Icon className="h-4 w-4 opacity-70" />
          1. Thông tin
        </h3>
        <div className="grid grid-cols-1 md:grid-cols-2 gap-3 text-sm">
          {config.detailFields.map((f) => (
            <div key={f.label}>
              <Label className="text-muted-foreground">{f.label}</Label>
              <div className="mt-1 font-medium whitespace-pre-wrap">{f.render(d)}</div>
            </div>
          ))}
          <div>
            <Label className="text-muted-foreground">Ngày tạo</Label>
            <div className="mt-1 text-xs">{formatDateTime(d.createdAt)}</div>
          </div>
        </div>
      </div>

      {/* Section 2: Quy trình duyệt */}
      <div className="rounded-lg border bg-card p-6 space-y-3">
        <h3 className="font-semibold text-base">2. Quy trình duyệt</h3>
        <div className="grid grid-cols-1 md:grid-cols-2 gap-3 text-sm">
          <div>
            <Label className="text-muted-foreground">Quy trình</Label>
            <div className="mt-1 text-xs">
              {d.workflowCode ? (
                <>
                  <span className="font-mono">{d.workflowCode}</span> - {d.workflowName}
                </>
              ) : '— Chưa chọn —'}
            </div>
          </div>
          <div>
            <Label className="text-muted-foreground">Cấp hiện tại</Label>
            <div className="mt-1 font-medium">{d.currentApprovalLevelOrder ?? '—'}</div>
          </div>
        </div>
      </div>

      {/* Section 3: Ý kiến cấp duyệt V2 dynamic */}
      <div className="rounded-lg border bg-card p-6 space-y-3">
        <h3 className="font-semibold text-base">3. Ý kiến cấp duyệt</h3>
        {d.levelOpinions.length === 0 ? (
          <div className="text-sm text-muted-foreground">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 border-l-4 border-emerald-400 bg-emerald-50/40 p-3">
                  <div className="flex items-center justify-between text-xs text-muted-foreground">
                    <span>
                      Bước {o.stepOrder} {o.stepName} · Cấp {o.levelOrder}
                    </span>
                    <span>{formatDateTime(o.signedAt)}</span>
                  </div>
                  <div className="mt-1 font-medium">{o.signedByFullName}</div>
                  <div className="mt-1 whitespace-pre-wrap text-sm">{o.comment ?? '(duyệt — không ý kiến)'}</div>
                </div>
              ))}
          </div>
        )}
      </div>

      {/* 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-muted-foreground">{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>
  )
}
