"use client";

import { updateCommissionRequestStatus } from "@/actions/commissions/requests/updateCommissionRequestStatus";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Kanban, KanbanBoard, KanbanColumn, KanbanItem, KanbanOverlay } from "@/components/ui/kanban";
import {
  BOARD_COLUMNS,
  type BoardColumnId,
  canonicalStatusForColumn,
} from "@/lib/commissions/kanban";
import Link from "next/link";
import * as React from "react";

type BoardItem = {
  id: string;
  createdAt: string;
  status: string;
  customerName: string;
  customerEmail: string;
  message: string;
  typeName: string | null;
  optionName: string | null;
  extrasCount: number;
  filesCount: number;
};

type ColumnsState = Record<BoardColumnId, BoardItem[]>;

import type { UniqueIdentifier } from "@dnd-kit/core";

type KanbanValue = Record<UniqueIdentifier, BoardItem[]>;

function isColumnsState(v: KanbanValue): v is ColumnsState {
  return (
    Array.isArray(v.intake) &&
    Array.isArray(v.inProgress) &&
    Array.isArray(v.completed)
  );
}

function asColumnsState(v: KanbanValue): ColumnsState {
  if (!isColumnsState(v)) {
    // Defensive: if something ever changes upstream, keep UI stable
    return { intake: [], inProgress: [], completed: [] };
  }
  return v;
}

function findItemColumn(columns: ColumnsState, itemId: string): BoardColumnId | null {
  for (const col of Object.keys(columns) as BoardColumnId[]) {
    if (columns[col].some((x) => x.id === itemId)) return col;
  }
  return null;
}

function diffMovedItem(prev: ColumnsState, next: ColumnsState) {
  const prevLoc = new Map<string, BoardColumnId>();
  const nextLoc = new Map<string, BoardColumnId>();

  for (const c of Object.keys(prev) as BoardColumnId[]) {
    for (const i of prev[c]) {
      prevLoc.set(i.id, c);
    }
  }

  for (const c of Object.keys(next) as BoardColumnId[]) {
    for (const i of next[c]) {
      nextLoc.set(i.id, c);
    }
  }

  for (const [id, from] of prevLoc.entries()) {
    const to = nextLoc.get(id);
    if (to && to !== from) return { id, from, to };
  }
  return null;
}

export default function CommissionsKanbanClient({
  initialColumns,
}: {
  initialColumns: ColumnsState;
}) {
  const [columns, setColumns] = React.useState<ColumnsState>(initialColumns);
  const prevRef = React.useRef(columns);

  React.useEffect(() => {
    prevRef.current = columns;
  }, [columns]);

  async function persistMove(moved: { id: string; to: BoardColumnId }, snapshotBefore: ColumnsState) {
    const status = canonicalStatusForColumn(moved.to);

    try {
      await updateCommissionRequestStatus({ id: moved.id, status });
      // optional: you could also update the item’s status in local state here
      // but revalidatePath + eventual refresh will keep it consistent anyway.
      setColumns((cur) => {
        const col = findItemColumn(cur, moved.id);
        if (!col) return cur;
        return {
          ...cur,
          [col]: cur[col].map((x) => (x.id === moved.id ? { ...x, status } : x)),
        };
      });
    } catch {
      // Revert optimistic state if update fails
      setColumns(snapshotBefore);
    }
  }

  function onValueChange(next: KanbanValue) {
    const nextColumns = asColumnsState(next);
    const prev = prevRef.current;

    setColumns(nextColumns);

    const moved = diffMovedItem(prev, nextColumns);
    if (!moved) return;

    void persistMove({ id: moved.id, to: moved.to }, prev);
  }

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between gap-3">
        <div>
          <h1 className="text-lg font-semibold">Commissions Board</h1>
          <p className="text-sm text-muted-foreground">
            Drag requests between columns to update their status.
          </p>
        </div>
        <Button asChild variant="outline">
          <Link href="/commissions/requests">Open list</Link>
        </Button>
      </div>

      <Kanban
        value={columns as unknown as KanbanValue}
        onValueChange={onValueChange}
        getItemValue={(item) => item.id}
      >
        <KanbanBoard className="grid auto-rows-fr gap-3 lg:grid-cols-3">
          {(Object.keys(columns) as BoardColumnId[]).map((colId) => {
            const col = BOARD_COLUMNS[colId];
            const items = columns[colId];

            return (
              <KanbanColumn key={colId} value={colId} className="rounded-lg border bg-card/50 p-3">
                <div className="mb-3 flex items-center justify-between">
                  <div className="flex items-center gap-2">
                    <span className="text-sm font-semibold">{col.title}</span>
                    <Badge variant="secondary" className="rounded-sm">
                      {items.length}
                    </Badge>
                  </div>
                </div>

                <div className="flex flex-col gap-2">
                  {items.map((item) => (
                    <KanbanItem key={item.id} value={item.id} asHandle asChild>
                      <div className="rounded-md border bg-background p-3 shadow-xs">
                        <div className="flex items-start justify-between gap-2">
                          <div className="min-w-0">
                            <div className="truncate text-sm font-medium">
                              {item.customerName}
                              <span className="text-muted-foreground"> — #{item.id.slice(0, 6)}</span>
                            </div>
                            <div className="truncate text-xs text-muted-foreground">
                              {item.typeName ?? "No type"}{item.optionName ? ` · ${item.optionName}` : ""}
                            </div>
                          </div>

                          <Badge variant="outline" className="rounded-sm text-[11px]">
                            {item.status}
                          </Badge>
                        </div>

                        <p className="mt-2 line-clamp-2 text-sm text-muted-foreground">
                          {item.message}
                        </p>

                        <div className="mt-3 flex items-center justify-between text-xs text-muted-foreground">
                          <span>
                            Files: {item.filesCount} · Extras: {item.extrasCount}
                          </span>
                          <Button asChild size="sm" variant="ghost" className="h-7 px-2">
                            <Link href={`/commissions/requests/${item.id}`}>Details</Link>
                          </Button>
                        </div>
                      </div>
                    </KanbanItem>
                  ))}
                </div>
              </KanbanColumn>
            );
          })}
        </KanbanBoard>

        <KanbanOverlay>
          <div className="size-full rounded-md bg-primary/10" />
        </KanbanOverlay>
      </Kanban>
    </div>
  );
}
