'use client';

import { useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import {
  Pencil,
  Archive,
  RotateCcw,
  Trophy,
  XCircle,
  RefreshCcw,
  Mail,
  MessageCircle,
  Phone,
} from 'lucide-react';
import Link from 'next/link';

import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { TagBadge } from '@/components/shared/tag-badge';
import { ArchiveConfirmDialog } from '@/components/shared/archive-confirm-dialog';
import { DetailHeaderStrip } from '@/components/shared/detail-header-strip';
import { PermissionGate } from '@/components/shared/permission-gate';
import { InterestForm } from '@/components/interests/interest-form';
import { InlineStagePicker } from '@/components/interests/inline-stage-picker';
import { InterestOutcomeDialog } from '@/components/interests/interest-outcome-dialog';
import { apiFetch } from '@/lib/api/client';
import { cn } from '@/lib/utils';

const OUTCOME_BADGE: Record<string, { label: string; className: string }> = {
  won: { label: 'Won', className: 'bg-emerald-100 text-emerald-700' },
  lost_other_marina: { label: 'Lost — other marina', className: 'bg-rose-100 text-rose-700' },
  lost_unqualified: { label: 'Lost — unqualified', className: 'bg-rose-100 text-rose-700' },
  lost_no_response: { label: 'Lost — no response', className: 'bg-rose-100 text-rose-700' },
  cancelled: { label: 'Cancelled', className: 'bg-slate-200 text-slate-700' },
};

const CATEGORY_LABELS: Record<string, string> = {
  general_interest: 'General',
  specific_qualified: 'Specific Qualified',
  hot_lead: 'Hot Lead',
};

interface InterestDetailHeaderProps {
  portSlug: string;
  interest: {
    id: string;
    clientId: string;
    clientName: string | null;
    /** Primary contact channels resolved from the linked client. The header
     *  uses these to render Email / Call / WhatsApp buttons so the rep
     *  doesn't have to navigate to the client page just to reach out. */
    clientPrimaryEmail?: string | null;
    clientPrimaryPhone?: string | null;
    clientPrimaryPhoneE164?: string | null;
    berthId: string | null;
    berthMooringNumber: string | null;
    pipelineStage: string;
    leadCategory: string | null;
    source: string | null;
    notes: string | null;
    reminderEnabled: boolean;
    reminderDays: number | null;
    archivedAt: string | null;
    outcome?: string | null;
    outcomeReason?: string | null;
    dateLastContact?: string | null;
    tags?: Array<{ id: string; name: string; color: string }>;
  };
}

function formatLastContactAge(iso: string): string {
  const days = Math.floor((Date.now() - new Date(iso).getTime()) / 86_400_000);
  if (days <= 0) return 'today';
  if (days === 1) return 'yesterday';
  if (days < 30) return `${days}d ago`;
  if (days < 365) return `${Math.floor(days / 30)}mo ago`;
  return `${Math.floor(days / 365)}y ago`;
}

export function InterestDetailHeader({ portSlug, interest }: InterestDetailHeaderProps) {
  const queryClient = useQueryClient();
  const [editOpen, setEditOpen] = useState(false);
  const [archiveOpen, setArchiveOpen] = useState(false);
  const [outcomeDialog, setOutcomeDialog] = useState<null | 'won' | 'lost'>(null);

  const isArchived = !!interest.archivedAt;
  const outcomeBadge = interest.outcome ? OUTCOME_BADGE[interest.outcome] : null;
  const isClosed = !!interest.outcome;

  // Contact deep-links — resolved from the linked client's primary channels.
  // wa.me requires the digits-only E.164 number (no leading "+"); fall back to
  // stripping non-digits from the display value when the canonical form is
  // missing.
  const whatsappNumber = interest.clientPrimaryPhoneE164
    ? interest.clientPrimaryPhoneE164.replace(/^\+/, '')
    : interest.clientPrimaryPhone
      ? interest.clientPrimaryPhone.replace(/[^\d]/g, '')
      : null;

  const reopenMutation = useMutation({
    mutationFn: () =>
      apiFetch(`/api/v1/interests/${interest.id}/outcome`, { method: 'DELETE', body: {} }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['interests', interest.id] });
      queryClient.invalidateQueries({ queryKey: ['interests'] });
    },
  });

  const archiveMutation = useMutation({
    mutationFn: () => apiFetch(`/api/v1/interests/${interest.id}`, { method: 'DELETE' }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['interests', interest.id] });
      queryClient.invalidateQueries({ queryKey: ['interests'] });
      setArchiveOpen(false);
    },
  });

  const restoreMutation = useMutation({
    mutationFn: () => apiFetch(`/api/v1/interests/${interest.id}/restore`, { method: 'POST' }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['interests', interest.id] });
      queryClient.invalidateQueries({ queryKey: ['interests'] });
      setArchiveOpen(false);
    },
  });

  const meta: Array<{ key: string; node: React.ReactNode }> = [];
  if (interest.berthMooringNumber) {
    meta.push({
      key: 'berth',
      node: (
        <Link
          href={`/${portSlug}/berths/${interest.berthId}`}
          className="text-foreground hover:underline"
        >
          Berth {interest.berthMooringNumber}
        </Link>
      ),
    });
  }
  if (interest.leadCategory) {
    meta.push({
      key: 'cat',
      node: <span>{CATEGORY_LABELS[interest.leadCategory] ?? interest.leadCategory}</span>,
    });
  }
  if (interest.source) {
    meta.push({
      key: 'src',
      node: <span className="capitalize">{interest.source}</span>,
    });
  }
  if (interest.dateLastContact) {
    meta.push({
      key: 'last',
      node: (
        <span className="text-foreground/70">
          Last contact {formatLastContactAge(interest.dateLastContact)}
        </span>
      ),
    });
  }

  return (
    <>
      <DetailHeaderStrip>
        <div className="flex items-start gap-2">
          <div className="min-w-0 flex-1 space-y-1.5">
            <div className="flex items-center gap-2 flex-wrap">
              <h1 className="truncate text-lg font-bold text-foreground sm:text-xl">
                {interest.clientName ?? 'Unknown Client'}
              </h1>
              {isArchived && (
                <Badge variant="secondary" className="text-xs">
                  Archived
                </Badge>
              )}
              {outcomeBadge ? (
                <span
                  className={cn(
                    'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium',
                    outcomeBadge.className,
                  )}
                  title={interest.outcomeReason ?? undefined}
                >
                  {outcomeBadge.label}
                </span>
              ) : (
                <PermissionGate
                  resource="interests"
                  action="change_stage"
                  fallback={
                    <span className="inline-flex items-center rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium text-gray-700">
                      {interest.pipelineStage}
                    </span>
                  }
                >
                  <InlineStagePicker
                    interestId={interest.id}
                    currentStage={interest.pipelineStage}
                    className="-ml-2.5"
                  />
                </PermissionGate>
              )}
            </div>

            {meta.length > 0 ? (
              <p className="text-xs text-muted-foreground sm:text-sm">
                {meta.map((m, i) => (
                  <span key={m.key}>
                    {i > 0 ? (
                      <span aria-hidden className="mx-1.5">
                        ·
                      </span>
                    ) : null}
                    {m.node}
                  </span>
                ))}
              </p>
            ) : null}

            {interest.tags && interest.tags.length > 0 && (
              <div className="flex flex-wrap gap-1 pt-0.5">
                {interest.tags.map((tag) => (
                  <TagBadge key={tag.id} name={tag.name} color={tag.color} />
                ))}
              </div>
            )}

            {/* Contact deep-links — let the rep email / call / WhatsApp the
                client without leaving the interest workspace. Resolved from
                the linked client's primary contact channels (server-side
                fetch in getInterestById). */}
            {interest.clientPrimaryEmail || interest.clientPrimaryPhone || whatsappNumber ? (
              <div className="flex flex-wrap items-center gap-1.5 pt-1">
                {interest.clientPrimaryEmail ? (
                  <Button
                    asChild
                    variant="outline"
                    size="sm"
                    className="h-8 gap-1.5 px-2.5 [&_svg]:size-3.5"
                  >
                    <a
                      href={`mailto:${interest.clientPrimaryEmail}`}
                      aria-label={`Email ${interest.clientPrimaryEmail}`}
                    >
                      <Mail />
                      Email
                    </a>
                  </Button>
                ) : null}
                {interest.clientPrimaryPhone ? (
                  <Button
                    asChild
                    variant="outline"
                    size="sm"
                    className="h-8 gap-1.5 px-2.5 [&_svg]:size-3.5"
                  >
                    <a
                      href={`tel:${interest.clientPrimaryPhone}`}
                      aria-label={`Call ${interest.clientPrimaryPhone}`}
                    >
                      <Phone />
                      Call
                    </a>
                  </Button>
                ) : null}
                {whatsappNumber ? (
                  <Button
                    asChild
                    variant="outline"
                    size="sm"
                    className="h-8 gap-1.5 px-2.5 [&_svg]:size-3.5"
                  >
                    <a
                      href={`https://wa.me/${whatsappNumber}`}
                      target="_blank"
                      rel="noopener noreferrer"
                      aria-label={`Message on WhatsApp`}
                    >
                      <MessageCircle />
                      WhatsApp
                    </a>
                  </Button>
                ) : null}
              </div>
            ) : null}
          </div>

          {/* Top-right actions. Won/Lost are sales-critical and read as text
               buttons on desktop; Edit/Archive stay icon-only. On mobile,
               Won/Lost shrink to icon buttons to keep the cluster from
               wrapping. */}
          <div className="flex shrink-0 items-center gap-1">
            <PermissionGate resource="interests" action="change_stage">
              {isClosed ? (
                <button
                  type="button"
                  onClick={() => reopenMutation.mutate()}
                  disabled={reopenMutation.isPending}
                  className={cn(
                    'inline-flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1 text-xs font-medium text-foreground transition-colors',
                    'hover:bg-foreground/5 disabled:opacity-50',
                  )}
                >
                  <RefreshCcw className="size-3.5" />
                  Reopen
                </button>
              ) : (
                <>
                  <button
                    type="button"
                    onClick={() => setOutcomeDialog('won')}
                    aria-label="Mark as won"
                    className={cn(
                      'inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-medium transition-colors',
                      'border border-emerald-200 bg-emerald-50 text-emerald-700',
                      'hover:bg-emerald-100',
                    )}
                  >
                    <Trophy className="size-3.5" />
                    <span className="hidden sm:inline">Mark won</span>
                  </button>
                  <button
                    type="button"
                    onClick={() => setOutcomeDialog('lost')}
                    aria-label="Close as lost"
                    className={cn(
                      'inline-flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-medium transition-colors',
                      'border border-rose-200 text-rose-700',
                      'hover:bg-rose-50',
                    )}
                  >
                    <XCircle className="size-3.5" />
                    <span className="hidden sm:inline">Close as lost</span>
                  </button>
                </>
              )}
            </PermissionGate>
            <PermissionGate resource="interests" action="edit">
              <button
                type="button"
                onClick={() => setEditOpen(true)}
                aria-label="Edit interest"
                title="Edit interest"
                className={cn(
                  'rounded-md p-1.5 text-muted-foreground/70 transition-colors',
                  'hover:bg-foreground/5 hover:text-foreground',
                )}
              >
                <Pencil className="size-4" />
              </button>
            </PermissionGate>
            <PermissionGate resource="interests" action="delete">
              <button
                type="button"
                onClick={() => setArchiveOpen(true)}
                aria-label={isArchived ? 'Restore interest' : 'Archive interest'}
                title={isArchived ? 'Restore interest' : 'Archive interest'}
                className={cn(
                  'rounded-md p-1.5 text-muted-foreground/70 transition-colors',
                  'hover:bg-foreground/5',
                  isArchived ? 'hover:text-foreground' : 'hover:text-destructive',
                )}
              >
                {isArchived ? <RotateCcw className="size-4" /> : <Archive className="size-4" />}
              </button>
            </PermissionGate>
          </div>
        </div>
      </DetailHeaderStrip>

      {outcomeDialog && (
        <InterestOutcomeDialog
          interestId={interest.id}
          mode={outcomeDialog}
          open={outcomeDialog !== null}
          onOpenChange={(open) => !open && setOutcomeDialog(null)}
        />
      )}

      <InterestForm
        open={editOpen}
        onOpenChange={setEditOpen}
        interest={interest as unknown as Parameters<typeof InterestForm>[0]['interest']}
      />

      <ArchiveConfirmDialog
        open={archiveOpen}
        onOpenChange={setArchiveOpen}
        entityName={interest.clientName ?? 'Interest'}
        entityType="Interest"
        isArchived={isArchived}
        onConfirm={() => {
          if (isArchived) {
            restoreMutation.mutate();
          } else {
            archiveMutation.mutate();
          }
        }}
        isLoading={archiveMutation.isPending || restoreMutation.isPending}
      />
    </>
  );
}
