import { useEffect, useState } from "react"
import { Check, Trash2 } from "lucide-react"

import { AppShell } from "~/components/layout/app-shell"
import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar"
import { Button } from "~/components/ui/button"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "~/components/ui/card"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu"
import { Input } from "~/components/ui/input"
import { Textarea } from "~/components/ui/textarea"
import { useAgents } from "~/lib/agents"
import { pageTitle } from "~/lib/page-meta"
import {
  DEFAULT_PROFILE,
  profileInitials,
  resetProfile,
  saveProfile,
  useProfile,
  type Profile,
} from "~/lib/profile"

export const meta = () => pageTitle("Profile")

export default function ProfileRoute() {
  const profile = useProfile()
  const agents = useAgents()
  const [draft, setDraft] = useState<Profile>(profile)
  const [savedAt, setSavedAt] = useState<number | null>(null)

  useEffect(() => {
    setDraft(profile)
  }, [profile])

  const dirty = JSON.stringify(draft) !== JSON.stringify(profile)
  const initials = profileInitials(draft.name || DEFAULT_PROFILE.name)

  const onPickAvatar = (file: File | null) => {
    if (!file) {
      setDraft((d) => ({ ...d, avatarUrl: "" }))
      return
    }
    const reader = new FileReader()
    reader.onload = () => {
      const result = reader.result
      if (typeof result === "string")
        setDraft((d) => ({ ...d, avatarUrl: result }))
    }
    reader.readAsDataURL(file)
  }

  const save = () => {
    saveProfile(draft)
    setSavedAt(Date.now())
  }

  const defaultAgent =
    agents.find((a) => a.id === draft.defaultAgentId) ?? null

  return (
    <AppShell title="Profile">
      <Card>
        <CardHeader>
          <CardTitle>You</CardTitle>
          <CardDescription>
            Personal info shown across the app — appbar avatar, signatures, and
            anywhere the assistant references you.
          </CardDescription>
        </CardHeader>
        <CardContent className="flex flex-col gap-6">
          <div className="flex flex-wrap items-center gap-4">
            <Avatar className="size-20 ring-2 ring-primary/30">
              {draft.avatarUrl ? (
                <AvatarImage src={draft.avatarUrl} alt={draft.name} />
              ) : null}
              <AvatarFallback className="bg-primary text-lg font-semibold text-primary-foreground">
                {initials}
              </AvatarFallback>
            </Avatar>
            <div className="flex flex-col gap-2">
              <label className="inline-flex w-fit cursor-pointer items-center gap-2 rounded-md border bg-background px-3 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground">
                <input
                  data-action="profile-avatar-upload"
                  type="file"
                  accept="image/*"
                  className="sr-only"
                  onChange={(e) => onPickAvatar(e.target.files?.[0] ?? null)}
                />
                Upload avatar
              </label>
              {draft.avatarUrl && (
                <Button
                  data-action="profile-avatar-remove"
                  variant="ghost"
                  size="sm"
                  onClick={() => onPickAvatar(null)}
                  className="w-fit text-muted-foreground"
                >
                  <Trash2 className="size-3.5" /> Remove
                </Button>
              )}
              <span className="text-xs text-muted-foreground">
                PNG, JPG, or SVG. Stored locally as a data URL.
              </span>
            </div>
          </div>

          <div className="grid gap-4 md:grid-cols-2">
            <Field label="Name">
              <Input
                data-action="profile-name"
                value={draft.name}
                onChange={(e) =>
                  setDraft((d) => ({ ...d, name: e.target.value }))
                }
                autoComplete="name"
              />
            </Field>
            <Field label="Email">
              <Input
                data-action="profile-email"
                type="email"
                value={draft.email}
                onChange={(e) =>
                  setDraft((d) => ({ ...d, email: e.target.value }))
                }
                autoComplete="email"
              />
            </Field>
            <Field label="Title" hint="Your role at work.">
              <Input
                data-action="profile-title"
                value={draft.title}
                onChange={(e) =>
                  setDraft((d) => ({ ...d, title: e.target.value }))
                }
                placeholder="e.g. Product designer"
              />
            </Field>
            <Field
              label="Default agent"
              hint="Used as the active persona on first load."
            >
              <DropdownMenu>
                <DropdownMenuTrigger
                  data-action="profile-default-agent"
                  className="inline-flex h-9 items-center justify-between gap-2 rounded-md border bg-background px-3 text-sm hover:bg-accent hover:text-accent-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                >
                  <span className="truncate">
                    {defaultAgent ? (
                      <>
                        <span className="font-medium">{defaultAgent.name}</span>
                        <span className="text-muted-foreground">
                          {" "}
                          — {defaultAgent.role}
                        </span>
                      </>
                    ) : (
                      "Use first available"
                    )}
                  </span>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="start" className="w-64">
                  <DropdownMenuItem
                    onClick={() =>
                      setDraft((d) => ({ ...d, defaultAgentId: "" }))
                    }
                    data-state={!draft.defaultAgentId ? "checked" : undefined}
                  >
                    First available
                  </DropdownMenuItem>
                  {agents.map((a) => (
                    <DropdownMenuItem
                      key={a.id}
                      onClick={() =>
                        setDraft((d) => ({ ...d, defaultAgentId: a.id }))
                      }
                      data-state={
                        draft.defaultAgentId === a.id ? "checked" : undefined
                      }
                      className="flex flex-col items-start"
                    >
                      <span className="font-medium">{a.name}</span>
                      <span className="text-xs text-muted-foreground">
                        {a.role}
                      </span>
                    </DropdownMenuItem>
                  ))}
                </DropdownMenuContent>
              </DropdownMenu>
            </Field>
          </div>

          <Field
            label="Bio"
            hint="A short blurb the assistant can reference (e.g. 'I work mostly in TypeScript')."
          >
            <Textarea
              data-action="profile-bio"
              value={draft.bio}
              onChange={(e) =>
                setDraft((d) => ({ ...d, bio: e.target.value }))
              }
              rows={3}
              placeholder="Tell the assistant about you."
            />
          </Field>

          <Field
            label="Signature"
            hint="Appended automatically when you ask the assistant to draft an email or note."
          >
            <Textarea
              data-action="profile-signature"
              value={draft.signature}
              onChange={(e) =>
                setDraft((d) => ({ ...d, signature: e.target.value }))
              }
              rows={3}
              placeholder={`Cheers,\n${draft.name || "Your name"}`}
            />
          </Field>

          <div className="flex flex-wrap items-center gap-2">
            <Button
              data-action="profile-save"
              onClick={save}
              disabled={!dirty}
            >
              Save
            </Button>
            <Button
              data-action="profile-revert"
              variant="ghost"
              onClick={() => setDraft(profile)}
              disabled={!dirty}
            >
              Revert
            </Button>
            <Button
              data-action="profile-reset"
              variant="ghost"
              onClick={() => {
                resetProfile()
                setSavedAt(Date.now())
              }}
            >
              Reset to defaults
            </Button>
            {savedAt && !dirty && (
              <span className="inline-flex items-center gap-1 text-sm text-emerald-700 dark:text-emerald-400">
                <Check className="size-4" /> Saved.
              </span>
            )}
          </div>
        </CardContent>
      </Card>
    </AppShell>
  )
}

function Field({
  label,
  hint,
  children,
}: {
  label: string
  hint?: string
  children: React.ReactNode
}) {
  return (
    <label className="flex flex-col gap-1.5">
      <span className="text-sm font-medium">{label}</span>
      {children}
      {hint && <span className="text-xs text-muted-foreground">{hint}</span>}
    </label>
  )
}
