import { useState, useMemo } from 'react';
import { pb } from '../../lib/pocketbase';
import { Search, X, ChevronRight, AlertTriangle } from 'lucide-react';
import type { TechnicianAssignment, AvailableRepairOrder } from '../../lib/technicianData';
import { fetchTechnicianAssignments, fetchAvailableRepairOrders, createTechnicianAssignment, clockElapsedMinutes, parseRepairOrderServices } from '../../lib/technicianData';
import { useTechnicianContext, useTechnicianNav } from '../../components/technician/TechnicianContext';
import { useToast } from '../../components/ui/Toast';
import { ListSkeleton } from '../../components/ui/ListSkeleton';
import { ListError } from '../../components/ui/ListError';
import { formatElapsed } from '../../lib/format';
import { usePagedList } from '../../hooks/usePagedList';

type StatusTab = 'all' | 'active' | 'completed' | 'available';

export default function TechnicianJobs() {
  const { navigateTech } = useTechnicianNav();
  const { showToast } = useToast();
  const { effectiveUserId, isImpersonating } = useTechnicianContext();
  const authUserId = pb.authStore.model?.id as string | undefined;

  const shopUserId = isImpersonating ? authUserId : (pb.authStore.model as Record<string, unknown>)?.shopUserId as string | undefined;

  const {
    items: assignments,
    loading,
    error: assignmentsError,
  } = usePagedList<TechnicianAssignment>(
    (page, perPage) => {
      if (!effectiveUserId) return Promise.resolve({ items: [], page: 1, perPage, totalItems: 0, totalPages: 1 });
      return fetchTechnicianAssignments(effectiveUserId, page, perPage);
    },
    50,
  );

  const {
    items: availableRDs,
    loading: availableLoading,
    error: availableError,
  } = usePagedList<AvailableRepairOrder>(
    (page, perPage) => {
      if (!shopUserId) return Promise.resolve({ items: [], page: 1, perPage, totalItems: 0, totalPages: 1 });
      return fetchAvailableRepairOrders(shopUserId, page, perPage);
    },
    50,
  );

  const [search, setSearch] = useState('');
  const [statusTab, setStatusTab] = useState<StatusTab>('active');
  const [claimingId, setClaimingId] = useState<string | null>(null);
  const [claimError, setClaimError] = useState<string | null>(null);

  const filtered = useMemo(() => {
    let list = assignments;
    if (statusTab === 'active') {
      list = list.filter(
        (a) =>
          a.status === 'pending' ||
          a.status === 'in_progress' ||
          a.status === 'waiting_parts',
      );
    } else if (statusTab === 'completed') {
      list = list.filter((a) => a.status === 'completed');
    }
    if (search.trim()) {
      const q = search.toLowerCase();
      list = list.filter(
        (a) =>
          a.roNumber?.toLowerCase().includes(q) ||
          a.vehicleInfo?.toLowerCase().includes(q) ||
          a.vin?.toLowerCase().includes(q),
      );
    }

    return list;
  }, [assignments, statusTab, search]);

  const assignedROIds = useMemo(() => {
    return new Set(assignments.map((a) => a.repairOrderId));
  }, [assignments]);

  const unclaimedRDs = useMemo(() => {
    return availableRDs.filter((ro) => !assignedROIds.has(ro.id));
  }, [availableRDs, assignedROIds]);

  const handleClaim = async (ro: AvailableRepairOrder) => {
    setClaimError(null);
    if (!effectiveUserId) {
      showToast('You must be signed in to claim a job.', 'error');
      return;
    }
    const shopUserId = isImpersonating ? authUserId : (pb.authStore.model as Record<string, unknown>)?.shopUserId as string | undefined;
    if (!shopUserId) {
      showToast('Your account is not linked to a shop. Contact your shop owner.', 'error');
      return;
    }
    setClaimingId(ro.id);
    try {
      const full = await pb.collection('repairOrders').getOne(ro.id) as Record<string, unknown>;
      const serviceList = parseRepairOrderServices(full.services).map((s) => ({
        id: s.id,
        name: s.name,
        description: s.description || '',
        status: s.status || 'pending',
      }));
      if (serviceList.length === 0) {
        showToast('This repair order has no services to claim.', 'error');
        setClaimingId(null);
        return;
      }
      const allIds = serviceList.map((s: { id: string }) => s.id);
      const assignment = await createTechnicianAssignment(
        {
          id: ro.id,
          roNumber: (full.roNumber as string) || '',
          vehicleInfo: (full.vehicleInfo as string) || '',
          vin: (full.vin as string) || '',
          mileage: (full.mileage as string) || '',
          serviceLocation: (full.serviceLocation as string) || '',
          services: serviceList,
        },
        effectiveUserId,
        allIds,
        shopUserId,
      );
      showToast('Job claimed successfully.', 'success');
      navigateTech(`/technician/jobs/${assignment.id}`);
    } catch (err) {
      console.error('Failed to claim job', err);
      showToast('Failed to claim job. Please try again.', 'error');
      setClaimingId(null);
    }
  };
  const tabs: { id: StatusTab; label: string }[] = [
    { id: 'active', label: 'Active' },
    { id: 'available', label: 'Available' },
    { id: 'all', label: 'All' },
    { id: 'completed', label: 'Completed' },
  ];

  return (
    <div className="mx-auto max-w-4xl space-y-4">
      {/* Search */}
      <div className="relative">
        <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
        <input
          type="text"
          placeholder="Search by RO#, vehicle, or VIN…"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          className="w-full rounded-xl border border-gray-200 bg-white py-3 pl-10 pr-10 text-sm text-gray-900 placeholder-gray-400 focus:border-green-400 focus:outline-none focus:ring-2 focus:ring-green-100 dark:border-gray-800 dark:bg-gray-900 dark:text-white dark:placeholder-gray-500 dark:focus:border-green-600 dark:focus:ring-green-900/30"
        />
        {search && (
          <button
            onClick={() => setSearch('')}
            className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
          >
            <X className="h-4 w-4" />
          </button>
        )}
      </div>

      {/* Tabs */}
      <div className="flex gap-1 rounded-xl bg-gray-100 p-1 dark:bg-gray-800">
        {tabs.map((tab) => (
          <button
            key={tab.id}
            onClick={() => setStatusTab(tab.id)}
            className={`flex-1 rounded-lg px-4 py-2 text-sm font-medium transition-colors ${
              statusTab === tab.id
                ? 'bg-white text-gray-900 shadow-sm dark:bg-gray-700 dark:text-white'
                : 'text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200'
            }`}
          >
            {tab.label}
          </button>
        ))}
      </div>

      {/* Error banner */}
      {claimError && (
        <div className="flex items-center gap-2 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-800/50 dark:bg-red-950/50 dark:text-red-400">
          <AlertTriangle className="h-4 w-4 shrink-0" />
          <span>{claimError}</span>
          <button onClick={() => setClaimError(null)} className="ml-auto shrink-0 text-red-400 hover:text-red-600 dark:hover:text-red-300">
            <X className="h-4 w-4" />
          </button>
        </div>
      )}

      {/* List */}
      {statusTab === 'available' ? (
        availableLoading ? (
          <ListSkeleton rows={4} />
        ) : availableError ? (
          <ListError title="Unable to load available jobs" message="Failed to load available repair orders." onRetry={() => window.location.reload()} />
        ) : unclaimedRDs.length === 0 ? (
          <div className="rounded-2xl border border-gray-200 bg-white p-12 text-center shadow-sm dark:border-gray-800 dark:bg-gray-900">
            <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-gray-100 dark:bg-gray-800">
              <Search className="h-6 w-6 text-gray-400 dark:text-gray-500" />
            </div>
            <p className="mt-4 text-sm text-gray-500 dark:text-gray-400">
              No active repair orders available to claim.
            </p>
          </div>
        ) : (
          <div className="space-y-3">
            {unclaimedRDs.map((ro) => {
              const statusBadge: Record<string, string> = {
                active: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',
                in_progress: 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400',
                waiting_parts: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400',
                waiting_pickup: 'bg-teal-100 text-teal-700 dark:bg-teal-900/30 dark:text-teal-400',
              };
              const badge = statusBadge[ro.status] ?? 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400';
              return (
                <div
                  key={ro.id}
                  className="rounded-2xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-800 dark:bg-gray-900"
                >
                  <div className="flex items-center justify-between gap-3">
                    <div className="min-w-0 flex-1">
                      <div className="flex items-center gap-2">
                        <span className="text-base font-bold text-gray-900 dark:text-white">
                          {ro.roNumber || '—'}
                        </span>
                        <span className={`rounded-full px-2 py-0.5 text-xs font-medium ${badge}`}>
                          {ro.status.replace(/_/g, ' ')}
                        </span>
                      </div>
                      <p className="mt-0.5 text-sm text-gray-600 dark:text-gray-400">
                        {ro.vehicleInfo || 'No vehicle info'}
                      </p>
                      <div className="mt-1 flex items-center gap-3 text-xs text-gray-400 dark:text-gray-500">
                        {ro.vin && <span>VIN {ro.vin}</span>}
                        {ro.mileage && <span>{ro.mileage} mi</span>}
                        <span>{ro.serviceCount} service{ro.serviceCount !== 1 ? 's' : ''}</span>
                      </div>
                    </div>
                    <button
                      onClick={() => handleClaim(ro)}
                      disabled={claimingId === ro.id}
                      className="shrink-0 rounded-xl bg-green-600 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-green-700 disabled:cursor-not-allowed disabled:opacity-60"
                    >
                      {claimingId === ro.id ? 'Claiming…' : 'Claim'}
                    </button>
                  </div>
                </div>
              );
            })}
          </div>
        )
      ) : loading ? (
        <ListSkeleton rows={4} />
      ) : assignmentsError ? (
        <ListError title="Unable to load assigned jobs" message="Failed to load your assigned jobs." onRetry={() => window.location.reload()} />
      ) : filtered.length === 0 ? (
        <div className="rounded-2xl border border-gray-200 bg-white p-12 text-center shadow-sm dark:border-gray-800 dark:bg-gray-900">
          <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-gray-100 dark:bg-gray-800">
            <Search className="h-6 w-6 text-gray-400 dark:text-gray-500" />
          </div>
          <p className="mt-4 text-sm text-gray-500 dark:text-gray-400">
            {search
              ? 'No results match your search.'
              : 'No assigned jobs yet.'}
          </p>
        </div>
      ) : (
        <div className="space-y-3">
          {filtered.map((job) => {
            const running = job.clockEntries.some((e) => !e.end);
            const statusColors: Record<string, string> = {
              pending: 'border-l-gray-300 dark:border-l-gray-700',
              in_progress: 'border-l-yellow-400 dark:border-l-yellow-600',
              waiting_parts: 'border-l-orange-400 dark:border-l-orange-600',
              completed: 'border-l-green-400 dark:border-l-green-600',
            };
            return (
              <button
                key={job.id}
                onClick={() => navigateTech(`/technician/jobs/${job.id}`)}
                className={`w-full rounded-2xl border border-gray-200 bg-white p-4 text-left shadow-sm transition-colors hover:border-green-300 dark:border-gray-800 dark:bg-gray-900 dark:hover:border-green-700 ${
                  statusColors[job.status] ?? 'border-l-gray-300'
                } border-l-4`}
              >
                <div className="flex items-center justify-between gap-3">
                  <div className="min-w-0 flex-1">
                    <div className="flex items-center gap-2">
                      <span className="text-base font-bold text-gray-900 dark:text-white">
                        {job.roNumber || '—'}
                      </span>
                      {job.status === 'waiting_parts' && (
                        <AlertTriangle className="h-4 w-4 text-orange-500" />
                      )}
                    </div>
                    <p className="mt-0.5 text-sm text-gray-600 dark:text-gray-400">
                      {job.vehicleInfo || 'No vehicle info'}
                    </p>
                    <div className="mt-1 flex items-center gap-3 text-xs text-gray-400 dark:text-gray-500">
                      {job.vin && <span>VIN {job.vin}</span>}
                      {job.mileage && <span>{job.mileage} mi</span>}
                    </div>
                  </div>
                  <div className="flex flex-col items-end gap-1.5">
                    {running && (
                      <span className="inline-flex items-center gap-1 rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-700 dark:bg-green-900/30 dark:text-green-400">
                        <span className="h-1.5 w-1.5 animate-pulse rounded-full bg-green-500" />
                        Clocked
                      </span>
                    )}
                    <span className="text-xs text-gray-400 dark:text-gray-500">
                      {formatElapsed(clockElapsedMinutes(job.clockEntries))}
                    </span>
                    <ChevronRight className="h-4 w-4 text-gray-300 dark:text-gray-600" />
                  </div>
                </div>
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}
