// Đề xuất chi tiết — Phase 10.3 G-O3 (S37 2026-05-28).
// 3 Section + WorkflowActions buttons + Ý kiến cấp duyệt V2 dynamic.
// File MIRROR SHA256 identical với fe-user counterpart.
//
// Re-skin (S69): PURO/Hồ sơ-NS visual language — ui/PageHeader (subject title +
// status badge) on top, info sections wrapped in .card-accent cards with
// .icon-chip headers, field rows in the Hồ sơ-NS Field idiom (label .label-eyebrow
// + value text-brand-800). Logic (queries, mutations, handlers, dialog) UNTOUCHED.
import { useState, type ReactNode } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useNavigate, useParams } from 'react-router-dom'
import {
  ArrowLeft, Ban, CheckCircle2, FileText, MessageSquare, Paperclip, RotateCcw, Send,
} 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 {
  PROPOSAL_STATUS_BADGE, PROPOSAL_STATUS_LABELS,
  ProposalStatus, type ProposalDetailDto, type ProposalStatusValue,
} from '@/types/proposal'

type ActionKind = 'approve' | 'reject' | 'return'

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

function formatDateTime(iso: string): string {
  const d = new Date(iso)
  return d.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' },
}

// Section card — .card-accent shell + .icon-chip header (Hồ sơ-NS idiom).
function SectionCard({
  title, icon, accent, head, chipBg, chipFg, count, children,
}: {
  title: string
  icon: ReactNode
  accent: string
  head: string
  chipBg: string
  chipFg: string
  count?: number
  children: ReactNode
}) {
  return (
    <section className="card-accent" style={{ ['--accent' as string]: accent }}>
      <header className="flex items-center gap-2 border-b border-slate-100 px-5 py-3">
        <span
          className="icon-chip"
          style={{ height: '1.75rem', width: '1.75rem', ['--chip-bg' as string]: chipBg, ['--chip-fg' as string]: chipFg }}
          aria-hidden
        >
          {icon}
        </span>
        <h3 className={cn('text-sm font-semibold tracking-tight', head)}>{title}</h3>
        {count != null && (
          <span className="rounded-full bg-slate-100 px-1.5 py-0.5 text-[10px] font-semibold tabular-nums text-slate-500">
            {count}
          </span>
        )}
      </header>
      <div className="p-5">{children}</div>
    </section>
  )
}

// Field — label .label-eyebrow style + value text-brand-800 (Hồ sơ-NS idiom).
function Field({
  label, value, mono, full, children,
}: {
  label: string
  value?: ReactNode
  mono?: boolean
  full?: boolean
  children?: ReactNode
}) {
  const empty = value == null || value === ''
  return (
    <div className={cn('min-w-0 text-sm', full && 'sm:col-span-2')}>
      <div className="text-[11px] font-semibold uppercase tracking-wide text-brand-600">{label}</div>
      <div className={cn('mt-0.5 break-words text-sm', empty && !children ? 'text-slate-300' : 'font-medium text-brand-800', mono && !empty && 'font-mono')}>
        {children ?? (empty ? '—' : value)}
      </div>
    </div>
  )
}

export function ProposalDetailPage() {
  const { id } = useParams<{ id: string }>()
  const navigate = useNavigate()
  const qc = useQueryClient()

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

  const proposal = useQuery({
    queryKey: ['proposal', id],
    queryFn: async () => (await api.get<ProposalDetailDto>(`/proposals/${id}`)).data,
    enabled: !!id,
  })

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: ['proposal', id] })
    qc.invalidateQueries({ queryKey: ['proposals'] })
  }

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

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

  if (proposal.isLoading) {
    return (
      <div className="space-y-5">
        <PageHeader eyebrow="Văn phòng số" title="Đang tải..." icon={<FileText className="h-5 w-5" />} />
      </div>
    )
  }

  if (proposal.isError || !proposal.data) {
    return (
      <div className="space-y-5">
        <PageHeader
          eyebrow="Văn phòng số"
          title="Lỗi"
          icon={<FileText className="h-5 w-5" />}
          actions={
            <Button variant="outline" onClick={() => navigate('/proposals')}>
              <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 đề xuất.
        </div>
      </div>
    )
  }

  const p = proposal.data
  const status = p.status as ProposalStatusValue
  const isDraft = status === ProposalStatus.Nhap || status === ProposalStatus.TraLai
  const isInWorkflow = status === ProposalStatus.DaGuiDuyet

  return (
    <div className="space-y-5">
      <PageHeader
        eyebrow={p.maDeXuat ?? 'Đề xuất'}
        title={p.title}
        icon={<FileText className="h-5 w-5" />}
        accent="brand"
        actions={
          <>
            <span
              className={cn(
                'inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-medium',
                PROPOSAL_STATUS_BADGE[status],
              )}
            >
              {PROPOSAL_STATUS_LABELS[status]}
            </span>
            <Button variant="outline" onClick={() => navigate('/proposals')}>
              <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',
              PROPOSAL_STATUS_BADGE[status],
            )}
          >
            {PROPOSAL_STATUS_LABELS[status]}
          </span>
          {p.currentApprovalLevelOrder && (
            <span className="text-sm text-muted-foreground">
              Cấp duyệt hiện tại: <span className="font-semibold">{p.currentApprovalLevelOrder}</span>
            </span>
          )}
          {p.workflowCode && (
            <span className="text-sm text-muted-foreground">
              Quy trình: <span className="font-mono">{p.workflowCode}</span>
            </span>
          )}
        </div>
        <div className="flex flex-wrap gap-2">
          {isDraft && (
            <Button onClick={() => submit.mutate()} disabled={submit.isPending}>
              <Send className="mr-2 h-4 w-4" />
              {status === ProposalStatus.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>

      {/* Section 1: Thông tin */}
      <SectionCard
        title="Thông tin đề xuất"
        icon={<FileText className="h-4 w-4" />}
        accent="var(--color-brand-500)"
        head="text-brand-800"
        chipBg="var(--color-brand-50)"
        chipFg="var(--color-brand-600)"
      >
        <div className="grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-4">
          <Field label="Tiêu đề" value={p.title} />
          <Field label="Số tiền dự kiến" value={formatVnd(p.amountEstimate)} mono />
          <Field label="Phòng ban" value={p.departmentName ?? '—'} />
          <Field label="Người soạn" value={p.drafterFullName ?? '—'} />
          <Field label="Quy trình">
            {p.workflowCode ? (
              <span>
                <span className="font-mono">{p.workflowCode}</span> - {p.workflowName}
              </span>
            ) : (
              <span className="text-slate-300">— Chưa chọn —</span>
            )}
          </Field>
          <Field label="Ngày tạo" value={formatDateTime(p.createdAt)} />
          {p.description && (
            <Field label="Nội dung chi tiết" full>
              <span className="whitespace-pre-wrap font-normal text-slate-700">{p.description}</span>
            </Field>
          )}
        </div>
      </SectionCard>

      {/* Section 2: Attachments */}
      <SectionCard
        title="File đính kèm"
        icon={<Paperclip className="h-4 w-4" />}
        accent="var(--color-teal-500)"
        head="text-teal-700"
        chipBg="var(--color-teal-50)"
        chipFg="var(--color-teal-700)"
        count={p.attachments.length}
      >
        {p.attachments.length === 0 ? (
          <div className="text-sm text-muted-foreground">Chưa có file đính kèm.</div>
        ) : (
          <ul className="space-y-2">
            {p.attachments.map((a) => (
              <li key={a.id} className="flex items-center justify-between rounded-lg border border-slate-200 p-2.5 text-sm">
                <div>
                  <div className="font-medium text-brand-800">{a.fileName}</div>
                  <div className="text-xs text-muted-foreground">
                    {a.uploadedByFullName} · {(a.fileSize / 1024).toFixed(1)} KB
                  </div>
                </div>
                <a href={a.filePath} target="_blank" rel="noreferrer" className="text-primary text-xs">
                  Tải xuống
                </a>
              </li>
            ))}
          </ul>
        )}
      </SectionCard>

      {/* Section 3: Ý kiến cấp duyệt V2 dynamic */}
      <SectionCard
        title="Ý kiến cấp duyệt"
        icon={<MessageSquare className="h-4 w-4" />}
        accent="var(--color-violet-500)"
        head="text-violet-700"
        chipBg="var(--color-violet-50)"
        chipFg="var(--color-violet-700)"
        count={p.levelOpinions.length}
      >
        {p.levelOpinions.length === 0 ? (
          <div className="text-sm text-muted-foreground">
            {status === ProposalStatus.Nhap
              ? 'Chưa gửi duyệt — chưa có ý kiến.'
              : 'Chưa có cấp nào duyệt.'}
          </div>
        ) : (
          <div className="space-y-3">
            {p.levelOpinions.map((o) => (
              <div key={o.id} className="rounded-lg 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 text-brand-800">{o.signedByFullName}</div>
                <div className="mt-1 whitespace-pre-wrap text-sm">{o.comment ?? '(duyệt — không ý kiến)'}</div>
              </div>
            ))}
          </div>
        )}
      </SectionCard>

      {/* Action confirm dialog */}
      <Dialog
        open={!!actionDialog}
        onClose={() => {
          setActionDialog(null)
          setComment('')
        }}
        title={actionDialog ? `${ACTION_LABEL[actionDialog].text} đề xuấ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>
  )
}
