"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import {
  MagnifyingGlassIcon,
  CheckCircleIcon,
} from "@heroicons/react/24/outline";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/app/shadcn_components/ui/dialog";
import { describeCandidate } from "@/lib/postcodeSearch/model";
import {
  searchAddresses,
  useAssignUprn,
  type SearchCandidate,
} from "@/lib/properties/client";
import type { UnmatchedProperty } from "@/lib/properties/unmatched";

// Row action for an unmatched property: edit the address, confirm the postcode,
// search Ordnance Survey, and pick from the RESIDENTIAL addresses in that
// postcode. Picking assigns that candidate's UPRN — every candidate is a real
// OS address, so this guarantees a valid, residential UPRN. On success the
// property leaves the "Needs attention" tab (the page re-fetches).
export default function MatchAddress({
  property,
  portfolioId,
}: {
  property: UnmatchedProperty;
  portfolioId: string;
}) {
  const router = useRouter();
  const [open, setOpen] = useState(false);
  const [address, setAddress] = useState(property.address ?? "");
  const [postcode, setPostcode] = useState(property.postcode ?? "");
  // null = not searched yet; [] = searched, no residential matches.
  const [residential, setResidential] = useState<SearchCandidate[] | null>(null);
  const [selected, setSelected] = useState<SearchCandidate | null>(null);
  const [source, setSource] = useState<"cache" | "live" | null>(null);
  const [searching, setSearching] = useState(false);
  const [searchError, setSearchError] = useState<string | null>(null);

  const assign = useAssignUprn(portfolioId, property.id);

  async function runSearch() {
    setSearching(true);
    setSearchError(null);
    setResidential(null);
    setSelected(null);
    try {
      const result = await searchAddresses(portfolioId, postcode);
      // Residential only — we never assign a non-residential UPRN.
      setResidential(result.candidates.filter((c) => c.selectable));
      setSource(result.source);
    } catch (e) {
      setSearchError(e instanceof Error ? e.message : "Search failed.");
    } finally {
      setSearching(false);
    }
  }

  function onAssign() {
    if (!selected) return;
    assign.mutate(
      {
        uprn: selected.uprn,
        address: selected.address,
        postcode: selected.postcode,
        userInputtedAddress: address.trim() || undefined,
        userInputtedPostcode: postcode.trim() || undefined,
      },
      {
        onSuccess: () => {
          setOpen(false);
          router.refresh();
        },
      },
    );
  }

  return (
    <>
      <button
        type="button"
        onClick={() => setOpen(true)}
        className="inline-flex items-center gap-1.5 rounded-lg border border-amber-300 bg-white px-3 py-1.5 text-xs font-semibold text-amber-800 transition-colors hover:bg-amber-100"
      >
        <MagnifyingGlassIcon className="h-3.5 w-3.5" />
        Find UPRN
      </button>

      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>Match to a UPRN</DialogTitle>
            <DialogDescription>
              Confirm the postcode and pick the matching address. Only
              residential addresses from Ordnance Survey are shown, so the UPRN
              is always valid.
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-3">
            <div>
              <label className="mb-1 block text-xs font-semibold text-gray-600">
                Address
              </label>
              <input
                value={address}
                onChange={(e) => setAddress(e.target.value)}
                placeholder="e.g. 20 Brenchley Road"
                className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-amber-400 focus:outline-none focus:ring-1 focus:ring-amber-400"
              />
            </div>
            <div className="flex items-end gap-2">
              <div className="flex-1">
                <label className="mb-1 block text-xs font-semibold text-gray-600">
                  Postcode
                </label>
                <input
                  value={postcode}
                  onChange={(e) => setPostcode(e.target.value)}
                  placeholder="e.g. BR5 2TD"
                  onKeyDown={(e) => {
                    if (e.key === "Enter" && postcode.trim() && !searching)
                      runSearch();
                  }}
                  className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm uppercase focus:border-amber-400 focus:outline-none focus:ring-1 focus:ring-amber-400"
                />
              </div>
              <button
                type="button"
                onClick={runSearch}
                disabled={!postcode.trim() || searching}
                className="inline-flex items-center gap-1.5 rounded-lg bg-amber-600 px-4 py-2 text-sm font-semibold text-white transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:bg-amber-300"
              >
                <MagnifyingGlassIcon className="h-4 w-4" />
                {searching ? "Searching…" : "Search"}
              </button>
            </div>

            {searchError && <p className="text-xs text-red-600">{searchError}</p>}

            {residential && (
              <div>
                <div className="mb-1 flex items-center justify-between">
                  <p className="text-xs font-semibold text-gray-600">
                    Residential addresses
                  </p>
                  {source === "cache" && (
                    <span className="text-[10px] font-medium uppercase tracking-wide text-gray-400">
                      from cache
                    </span>
                  )}
                </div>
                <div className="max-h-64 overflow-y-auto rounded-lg border border-gray-100">
                  {residential.length === 0 ? (
                    <p className="px-3 py-6 text-center text-sm text-gray-400">
                      No residential addresses found for that postcode.
                    </p>
                  ) : (
                    <ul className="divide-y divide-gray-50">
                      {residential.map((c) => {
                        const { label } = describeCandidate(c);
                        const disabled = c.alreadyInPortfolio;
                        const isSelected = selected?.uprn === c.uprn;
                        return (
                          <li key={c.uprn}>
                            <button
                              type="button"
                              disabled={disabled}
                              onClick={() => setSelected(c)}
                              className={`flex w-full items-start gap-2 px-3 py-2 text-left text-sm transition-colors ${
                                disabled
                                  ? "cursor-not-allowed text-gray-400"
                                  : isSelected
                                    ? "bg-amber-50"
                                    : "hover:bg-gray-50"
                              }`}
                            >
                              <CheckCircleIcon
                                className={`mt-0.5 h-4 w-4 shrink-0 ${
                                  isSelected ? "text-amber-600" : "text-gray-200"
                                }`}
                              />
                              <span className="min-w-0 flex-1">
                                <span
                                  className="block truncate text-gray-800"
                                  title={c.address}
                                >
                                  {c.address}
                                </span>
                                <span className="block truncate text-[11px] text-gray-500">
                                  UPRN {c.uprn} · {label}
                                  {c.alreadyInPortfolio
                                    ? " · already in portfolio"
                                    : ""}
                                </span>
                              </span>
                            </button>
                          </li>
                        );
                      })}
                    </ul>
                  )}
                </div>
              </div>
            )}
          </div>

          <DialogFooter>
            {assign.error && (
              <p className="mr-auto self-center text-xs text-red-600">
                {assign.error.message}
              </p>
            )}
            <button
              type="button"
              onClick={() => setOpen(false)}
              className="rounded-lg px-4 py-2 text-sm font-semibold text-gray-600 hover:bg-gray-100"
            >
              Cancel
            </button>
            <button
              type="button"
              onClick={onAssign}
              disabled={!selected || assign.isPending}
              className="rounded-lg bg-amber-600 px-4 py-2 text-sm font-bold text-white transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:bg-amber-300"
            >
              {assign.isPending ? "Assigning…" : "Assign UPRN"}
            </button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
