import * as api from "@client/api";
import type { UpdateSettingsInput } from "@shared/settings-schema.js";
import type { JobSearchProfile, SearchProfile } from "@shared/types.js";
import { Loader2, Plus, Sparkles, Trash2 } from "lucide-react";
import type React from "react";
import { useCallback, useEffect, useState } from "react";
import { useFormContext } from "react-hook-form";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";

const EMPTY_PROFILE: JobSearchProfile = {
  targetRoles: [],
  experienceLevel: "",
  mustHaveSkills: [],
  niceToHaveSkills: [],
  dealBreakers: [],
  preferredWorkArrangement: [],
  preferredLocations: [],
  minimumSalary: "",
  industriesToTarget: [],
  industriesToAvoid: [],
  aboutMe: "",
};

interface ProfileManagerProps {
  activeProfileId: string | null;
  disabled: boolean;
}

export const ProfileManager: React.FC<ProfileManagerProps> = ({
  activeProfileId,
  disabled,
}) => {
  const { setValue } = useFormContext<UpdateSettingsInput>();
  const [profiles, setProfiles] = useState<SearchProfile[]>([]);
  const [selectedId, setSelectedId] = useState<string | null>(activeProfileId);
  const [loading, setLoading] = useState(false);
  const [generating, setGenerating] = useState(false);
  const [newProfileName, setNewProfileName] = useState("");
  const [showCreate, setShowCreate] = useState(false);

  const loadProfiles = useCallback(async () => {
    try {
      const list = await api.listProfiles();
      setProfiles(list);
    } catch {
      toast.error("Failed to load profiles");
    }
  }, []);

  useEffect(() => {
    void loadProfiles();
  }, [loadProfiles]);

  useEffect(() => {
    setSelectedId(activeProfileId);
  }, [activeProfileId]);

  const handleSelect = useCallback(
    async (profileId: string) => {
      setLoading(true);
      try {
        await api.activateProfile(profileId);
        setSelectedId(profileId);
        const profile = profiles.find((p) => p.id === profileId);
        if (profile) {
          setValue("jobSearchProfile", profile.data, { shouldDirty: false });
          setValue("activeProfileId", profileId, { shouldDirty: false });
        }
        toast.success("Profile activated");
      } catch {
        toast.error("Failed to activate profile");
      } finally {
        setLoading(false);
      }
    },
    [profiles, setValue],
  );

  const handleCreateBlank = useCallback(async () => {
    if (!newProfileName.trim()) {
      toast.error("Enter a profile name");
      return;
    }
    setLoading(true);
    try {
      const profile = await api.createProfile({
        name: newProfileName.trim(),
        data: EMPTY_PROFILE,
      });
      await api.activateProfile(profile.id);
      setProfiles((prev) => [...prev, profile]);
      setSelectedId(profile.id);
      setValue("jobSearchProfile", profile.data, { shouldDirty: false });
      setValue("activeProfileId", profile.id, { shouldDirty: false });
      setNewProfileName("");
      setShowCreate(false);
      toast.success(`Profile "${profile.name}" created`);
    } catch {
      toast.error("Failed to create profile");
    } finally {
      setLoading(false);
    }
  }, [newProfileName, setValue]);

  const handleGenerateFromResume = useCallback(async () => {
    if (!newProfileName.trim()) {
      toast.error("Enter a profile name first");
      return;
    }
    setGenerating(true);
    try {
      const generated = await api.generateProfileFromResume();
      const profile = await api.createProfile({
        name: newProfileName.trim(),
        data: generated,
      });
      await api.activateProfile(profile.id);
      setProfiles((prev) => [...prev, profile]);
      setSelectedId(profile.id);
      setValue("jobSearchProfile", profile.data, { shouldDirty: false });
      setValue("activeProfileId", profile.id, { shouldDirty: false });
      setNewProfileName("");
      setShowCreate(false);
      toast.success(`Profile "${profile.name}" created from your resume`);
    } catch (err) {
      const msg =
        err instanceof Error ? err.message : "Failed to generate profile";
      toast.error(msg);
    } finally {
      setGenerating(false);
    }
  }, [newProfileName, setValue]);

  const handleDelete = useCallback(
    async (profileId: string) => {
      try {
        await api.deleteProfile(profileId);
        setProfiles((prev) => prev.filter((p) => p.id !== profileId));
        if (selectedId === profileId) {
          setSelectedId(null);
          setValue("jobSearchProfile", EMPTY_PROFILE, { shouldDirty: false });
          setValue("activeProfileId", null, { shouldDirty: false });
        }
        toast.success("Profile deleted");
      } catch {
        toast.error("Failed to delete profile");
      }
    },
    [selectedId, setValue],
  );

  const activeProfile = profiles.find((p) => p.id === selectedId);

  return (
    <div className="space-y-3 mb-4">
      <div className="flex flex-col gap-2">
        <div className="flex items-center gap-2">
          <select
            className="flex h-9 flex-1 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
            value={selectedId ?? ""}
            onChange={(e) => {
              if (e.target.value) void handleSelect(e.target.value);
            }}
            disabled={disabled || loading || generating}
          >
            <option value="">
              {profiles.length === 0
                ? "No profiles — create one"
                : "Select a profile..."}
            </option>
            {profiles.map((p) => (
              <option key={p.id} value={p.id}>
                {p.name}
              </option>
            ))}
          </select>
          <Button
            type="button"
            size="sm"
            variant="outline"
            onClick={() => setShowCreate(!showCreate)}
            disabled={disabled || generating}
          >
            <Plus className="h-3.5 w-3.5 mr-1" />
            New
          </Button>
          {activeProfile && (
            <Button
              type="button"
              size="icon"
              variant="ghost"
              className="h-9 w-9 text-muted-foreground hover:text-destructive"
              onClick={() => void handleDelete(activeProfile.id)}
              disabled={disabled || generating}
            >
              <Trash2 className="h-3.5 w-3.5" />
            </Button>
          )}
        </div>

        {showCreate && (
          <div className="flex items-center gap-2 p-3 rounded-lg border border-dashed bg-muted/30">
            <Input
              value={newProfileName}
              onChange={(e) => setNewProfileName(e.target.value)}
              placeholder="Profile name (e.g. QA Engineer, DevOps)"
              className="flex-1 h-8 text-sm"
              disabled={generating}
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  e.preventDefault();
                  void handleCreateBlank();
                }
              }}
            />
            <Button
              type="button"
              size="sm"
              variant="outline"
              onClick={handleCreateBlank}
              disabled={!newProfileName.trim() || generating}
            >
              Create blank
            </Button>
            <Button
              type="button"
              size="sm"
              onClick={handleGenerateFromResume}
              disabled={!newProfileName.trim() || generating}
            >
              {generating ? (
                <Loader2 className="h-3.5 w-3.5 mr-1 animate-spin" />
              ) : (
                <Sparkles className="h-3.5 w-3.5 mr-1" />
              )}
              {generating ? "Analysing resume..." : "Generate from resume"}
            </Button>
          </div>
        )}
      </div>

      {!selectedId && profiles.length === 0 && (
        <p className="text-xs text-muted-foreground text-center py-2">
          Create a profile to get started. "Generate from resume" will analyse
          your local resume file and fill in the fields automatically.
        </p>
      )}
    </div>
  );
};
