import { Pencil, ShieldCheck, Trash2, type LucideIcon } from 'lucide-react';

import {
  Button,
  Card,
  CardContent,
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  Input,
  Label,
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
  Textarea,
  type EntityRow,
} from '@ump/shared';

import { asNum, asStr, fmt, pct, toneClass, type EntityConfig } from './cockpitConfig';

export function StatusBadge({ value }: { value: unknown }) {
  if (value === undefined || value === null || value === '') return null;
  return (
    <span className={'inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium ' + toneClass(value)}>
      {asStr(value)}
    </span>
  );
}

export function Stat({
  icon: Icon,
  label,
  value,
  sub,
  accent,
}: {
  icon: LucideIcon;
  label: string;
  value: string;
  sub?: string;
  accent?: string;
}) {
  return (
    <Card>
      <CardContent className="p-4">
        <div className="flex items-center gap-2 text-xs font-medium text-muted-foreground">
          <Icon size={15} className={accent} /> {label}
        </div>
        <div className="mt-2 text-2xl font-semibold tabular-nums text-foreground">{value}</div>
        {sub && <div className="mt-0.5 text-xs text-muted-foreground">{sub}</div>}
      </CardContent>
    </Card>
  );
}

export function Bar({ value, tone = 'bg-primary' }: { value: unknown; tone?: string }) {
  return (
    <div className="h-2 w-full overflow-hidden rounded-full bg-muted">
      <div className={'h-full rounded-full ' + tone} style={{ width: pct(value) + '%' }} />
    </div>
  );
}

export function EntityCard({
  config,
  item,
  canEdit,
  onEdit,
  onDelete,
}: {
  config: EntityConfig;
  item: EntityRow;
  canEdit: boolean;
  onEdit: () => void;
  onDelete: () => void;
}) {
  const isNumField = (k: string) => config.fields.some((f) => f.key === k && f.type === 'number');
  const sub = config.secondary
    .map(([k, sfx]) => {
      const v = item[k];
      if (v === undefined || v === '' || v === null) return null;
      return (isNumField(k) ? fmt(v) : asStr(v)) + (sfx || '');
    })
    .filter(Boolean);

  const progressTone =
    item.status === 'Trễ hạn' ? 'bg-rose-500' : item.status === 'Hoàn thành' ? 'bg-emerald-500' : 'bg-primary';

  return (
    <Card className="card-hover">
      <CardContent className="p-4">
        <div className="flex items-start justify-between gap-2">
          <div className="min-w-0">
            <div className="font-semibold leading-snug text-foreground">{asStr(item[config.primary]) || '—'}</div>
            {sub.length > 0 && <div className="mt-0.5 text-xs text-muted-foreground">{sub.join(' · ')}</div>}
          </div>
          {config.badge && <StatusBadge value={item[config.badge]} />}
        </div>

        {config.accessKey && item[config.accessKey] ? (
          <div className="mt-2 inline-flex items-center gap-1 rounded-md border border-violet-200 bg-violet-50 px-2 py-0.5 text-xs text-violet-700">
            <ShieldCheck size={12} /> {asStr(item[config.accessKey])}
          </div>
        ) : null}

        {config.metrics && item.status !== 'Kế hoạch' && (
          <div className="mt-3 flex flex-wrap gap-1.5">
            {config.metrics.map(([k, lbl]) =>
              asNum(item[k]) > 0 ? (
                <span key={k} className="rounded-md border border-border bg-muted/50 px-2 py-0.5 text-xs text-muted-foreground">
                  {lbl} <b className="tabular-nums text-foreground">{asNum(item[k]).toFixed(2)}</b>
                </span>
              ) : null,
            )}
          </div>
        )}

        {config.progress && (
          <div className="mt-3">
            <div className="mb-1 flex justify-between text-xs text-muted-foreground">
              <span className="truncate pr-2">{asStr(item.deliverable)}</span>
              <span className="tabular-nums">{pct(item[config.progress])}%</span>
            </div>
            <Bar value={item[config.progress]} tone={progressTone} />
          </div>
        )}

        <div className="mt-3 flex justify-end gap-1 border-t border-border pt-2">
          <button
            onClick={onEdit}
            disabled={!canEdit}
            title={canEdit ? 'Sửa' : 'Không có quyền'}
            className={'p-1 ' + (canEdit ? 'text-muted-foreground hover:text-primary' : 'cursor-not-allowed text-muted-foreground/40')}
          >
            <Pencil size={15} />
          </button>
          <button
            onClick={onDelete}
            disabled={!canEdit}
            title={canEdit ? 'Xóa' : 'Không có quyền'}
            className={'p-1 ' + (canEdit ? 'text-muted-foreground hover:text-destructive' : 'cursor-not-allowed text-muted-foreground/40')}
          >
            <Trash2 size={15} />
          </button>
        </div>
      </CardContent>
    </Card>
  );
}

export function EntityDrawer({
  open,
  isNew,
  config,
  draft,
  onChange,
  onSave,
  onClose,
  saving,
}: {
  open: boolean;
  isNew: boolean;
  config: EntityConfig;
  draft: Record<string, string>;
  onChange: (key: string, value: string) => void;
  onSave: () => void;
  onClose: () => void;
  saving: boolean;
}) {
  return (
    <Dialog open={open} onOpenChange={(o) => !o && onClose()}>
      <DialogContent className="max-h-[85vh] overflow-y-auto sm:max-w-lg">
        <DialogHeader>
          <DialogTitle className="font-serif">
            {isNew ? 'Thêm ' : 'Sửa '}
            {config.singular}
          </DialogTitle>
        </DialogHeader>
        <div className="space-y-3.5 py-2">
          {config.fields.map((f) => (
            <div key={f.key}>
              <Label className="mb-1 block text-xs font-semibold text-muted-foreground">{f.label}</Label>
              {f.type === 'textarea' ? (
                <Textarea className="min-h-20" value={draft[f.key] ?? ''} onChange={(e) => onChange(f.key, e.target.value)} />
              ) : f.type === 'select' ? (
                <Select value={draft[f.key] || undefined} onValueChange={(v) => onChange(f.key, v)}>
                  <SelectTrigger>
                    <SelectValue placeholder="—" />
                  </SelectTrigger>
                  <SelectContent>
                    {f.options?.map((o) => (
                      <SelectItem key={o} value={o}>
                        {o}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              ) : (
                <Input
                  type={f.type === 'number' ? 'number' : 'text'}
                  min={f.min}
                  max={f.max}
                  step={f.step}
                  value={draft[f.key] ?? ''}
                  onChange={(e) => onChange(f.key, e.target.value)}
                />
              )}
            </div>
          ))}
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={onClose} disabled={saving}>
            Hủy
          </Button>
          <Button onClick={onSave} disabled={saving}>
            Lưu
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
