import { useState } from "react";
import { Users, Mail, Phone, Building2 } from "lucide-react";
import { trpc } from "@/lib/trpc";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { EntitySidebar } from "@/components/EntitySidebar";
import { EntitySearchSelect, type EntityOption } from "@/components/EntitySearchSelect";
import { CompanyDetailSheet, type CreatedCompany } from "@/components/CompanyDetailSheet";

export interface CreatedContact {
  id: number;
  firstName: string;
  lastName: string;
  mail?: string;
}

interface Company {
  id?: number;
  name?: string;
  website?: string;
}

interface ContactDetailSheetProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  contactId?: number | null;
  onSuccess?: (createdContact?: CreatedContact) => void;
  layer?: number;
}

export function ContactDetailSheet({
  open,
  onOpenChange,
  contactId,
  onSuccess,
  layer = 0,
}: ContactDetailSheetProps) {
  const isCreateMode = !contactId;

  // Company search state
  const [companySearchQuery, setCompanySearchQuery] = useState("");
  const [companySheetOpen, setCompanySheetOpen] = useState(false);

  const { data: contact, isLoading } = trpc.contacts.getById.useQuery(
    { id: contactId! },
    { enabled: !!contactId && open }
  );

  // Search companies
  const { data: companySearchResults, isLoading: isSearchingCompanies } = trpc.companies.search.useQuery(
    { query: companySearchQuery, limit: 5 },
    { enabled: open }
  );

  // Get initial company from contact data
  const getInitialCompany = (): EntityOption | null => {
    if (isCreateMode || !contact?.company?.[0]) return null;
    const company = contact.company[0] as Company;
    if (!company.id || !company.name) return null;
    return {
      id: company.id,
      name: company.name,
      subtitle: company.website,
    };
  };

  // Use contact data as initial values, track changes separately
  const initialFirstName = isCreateMode ? "" : (contact?.firstName || "");
  const initialLastName = isCreateMode ? "" : (contact?.lastName || "");
  const initialMail = isCreateMode ? "" : (contact?.mail || "");
  const initialPhone1 = isCreateMode ? "" : (contact?.phone1 || "");
  const initialPhone2 = isCreateMode ? "" : (contact?.phone2 || "");
  const initialNotes = isCreateMode ? "" : (contact?.notes || "");
  const initialCompany = getInitialCompany();

  const [firstName, setFirstName] = useState("");
  const [lastName, setLastName] = useState("");
  const [mail, setMail] = useState("");
  const [phone1, setPhone1] = useState("");
  const [phone2, setPhone2] = useState("");
  const [notes, setNotes] = useState("");
  const [selectedCompany, setSelectedCompany] = useState<EntityOption | null>(null);
  const [isInitialized, setIsInitialized] = useState(false);

  // Initialize form when data loads or sheet opens
  if (open && !isLoading && !isInitialized) {
    setFirstName(initialFirstName);
    setLastName(initialLastName);
    setMail(initialMail);
    setPhone1(initialPhone1);
    setPhone2(initialPhone2);
    setNotes(initialNotes);
    setSelectedCompany(initialCompany);
    setIsInitialized(true);
  }

  // Reset when sheet closes
  if (!open && isInitialized) {
    setIsInitialized(false);
  }

  // Check if company changed
  const companyChanged = isCreateMode
    ? selectedCompany !== null
    : (selectedCompany?.id !== initialCompany?.id);

  const hasChanges = isCreateMode 
    ? firstName.trim().length > 0 || lastName.trim().length > 0
    : (firstName !== initialFirstName || lastName !== initialLastName || mail !== initialMail || phone1 !== initialPhone1 || phone2 !== initialPhone2 || notes !== initialNotes || companyChanged);

  const createMutation = trpc.contacts.create.useMutation({
    onSuccess: (data) => {
      // Extract the created contact info to pass back
      const createdContact: CreatedContact | undefined = data?.id ? {
        id: data.id as number,
        firstName: firstName,
        lastName: lastName,
        mail: mail || undefined,
      } : undefined;
      onSuccess?.(createdContact);
      onOpenChange(false);
    },
  });

  const updateMutation = trpc.contacts.update.useMutation({
    onSuccess: () => {
      onSuccess?.();
      onOpenChange(false);
    },
  });

  const deleteMutation = trpc.contacts.delete.useMutation({
    onSuccess: () => {
      onSuccess?.();
      onOpenChange(false);
    },
  });

  const handleSave = () => {
    if (isCreateMode) {
      if (firstName.trim() && lastName.trim()) {
        createMutation.mutate({
          firstName,
          lastName,
          mail: mail || undefined,
          phone1: phone1 || undefined,
          phone2: phone2 || undefined,
          notes: notes || undefined,
          company: selectedCompany ? [selectedCompany.id] : undefined,
        });
      }
    } else if (contactId && hasChanges) {
      updateMutation.mutate({
        id: contactId,
        firstName: firstName || undefined,
        lastName: lastName || undefined,
        mail: mail || undefined,
        phone1: phone1 || undefined,
        phone2: phone2 || undefined,
        notes: notes || undefined,
        company: selectedCompany ? [selectedCompany.id] : [],
      });
    }
  };

  const handleDelete = () => {
    if (contactId) {
      deleteMutation.mutate({ id: contactId });
    }
  };

  // Handle company creation success
  const handleCompanyCreated = () => {
    setCompanySearchQuery("");
  };

  const isPending = createMutation.isPending || updateMutation.isPending;

  // Map company search results to EntityOption format
  const companyOptions: EntityOption[] = (companySearchResults || [])
    .filter((c): c is { id: number; name: string; website?: string } => 
      c.id !== undefined && c.name !== undefined
    )
    .map((company) => ({
      id: company.id,
      name: company.name,
      subtitle: company.website,
    }));

  return (
    <>
      <EntitySidebar
        open={open}
        onOpenChange={onOpenChange}
        title={isCreateMode ? "New Contact" : "Contact Details"}
        description={isCreateMode ? "Create a new contact record" : "View and edit contact information"}
        icon={<Users className="h-5 w-5 text-primary" />}
        isCreateMode={isCreateMode}
        isLoading={isLoading}
        hasChanges={hasChanges}
        isPending={isPending}
        isDeletePending={deleteMutation.isPending}
        onSave={handleSave}
        onDelete={isCreateMode ? undefined : handleDelete}
        layer={layer}
        footer={
          !isCreateMode && contact ? (
            <div className="pt-4 border-t">
              <p className="text-xs text-muted-foreground">
                Created: {contact.createdAt ? new Date(contact.createdAt).toLocaleDateString() : "-"}
                {contact.updatedAt && (
                  <> | Updated: {new Date(contact.updatedAt).toLocaleDateString()}</>
                )}
              </p>
            </div>
          ) : undefined
        }
      >
        <div className="grid grid-cols-2 gap-4">
          <div className="space-y-2">
            <Label htmlFor="firstName">First Name *</Label>
            <Input
              id="firstName"
              value={firstName}
              onChange={(e) => setFirstName(e.target.value)}
              placeholder="John"
            />
          </div>
          <div className="space-y-2">
            <Label htmlFor="lastName">Last Name *</Label>
            <Input
              id="lastName"
              value={lastName}
              onChange={(e) => setLastName(e.target.value)}
              placeholder="Doe"
            />
          </div>
        </div>

        <div className="space-y-2">
          <Label htmlFor="mail">Email</Label>
          <div className="relative">
            <Mail className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              id="mail"
              type="email"
              value={mail}
              onChange={(e) => setMail(e.target.value)}
              placeholder="john@example.com"
              className="pl-10"
            />
          </div>
        </div>

        <div className="grid grid-cols-2 gap-4">
          <div className="space-y-2">
            <Label htmlFor="phone1">Phone 1</Label>
            <div className="relative">
              <Phone className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
              <Input
                id="phone1"
                value={phone1}
                onChange={(e) => setPhone1(e.target.value)}
                placeholder="+1 234 567 890"
                className="pl-10"
              />
            </div>
          </div>
          <div className="space-y-2">
            <Label htmlFor="phone2">Phone 2</Label>
            <div className="relative">
              <Phone className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
              <Input
                id="phone2"
                value={phone2}
                onChange={(e) => setPhone2(e.target.value)}
                placeholder="+1 234 567 890"
                className="pl-10"
              />
            </div>
          </div>
        </div>

        <div className="space-y-2">
          <Label>Company</Label>
          <EntitySearchSelect
            value={selectedCompany}
            onChange={setSelectedCompany}
            onSearch={setCompanySearchQuery}
            onCreateNew={() => setCompanySheetOpen(true)}
            options={companyOptions}
            isLoading={isSearchingCompanies}
            placeholder="Select a company..."
            icon={Building2}
            entityName="Company"
          />
        </div>

        <div className="space-y-2 flex-1">
          <Label htmlFor="notes">Notes</Label>
          <Textarea
            id="notes"
            value={notes}
            onChange={(e) => setNotes(e.target.value)}
            placeholder="Add any notes about this contact..."
            className="min-h-[120px] resize-none"
          />
        </div>
      </EntitySidebar>

      {/* Nested Company Creation Sheet */}
      <CompanyDetailSheet
        open={companySheetOpen}
        onOpenChange={setCompanySheetOpen}
        companyId={null}
        layer={layer + 1}
        onSuccess={(newCompany?: CreatedCompany) => {
          handleCompanyCreated();
          if (newCompany) {
            setSelectedCompany({
              id: newCompany.id,
              name: newCompany.name,
              subtitle: newCompany.website,
            });
          }
          setCompanySheetOpen(false);
        }}
      />
    </>
  );
}
