"use client"

import * as React from "react"
import { useSearchParams } from "next/navigation"
import { useUrlPagination } from "@/hooks/use-url-pagination"
import { Contact, ContactStats } from "./types"
import { ContactListView } from "./contact-list-view"
import { ContactDetailModal } from "./contact-detail-modal"
import { Search, Download, Plus, Users, Flame, CheckCircle2, DollarSign, Target, Trash2, ArrowRightLeft } from "lucide-react"
import { toast } from "sonner"
import { AddContactModal } from "./add-contact-modal"
import { EditContactModal } from "./edit-contact-modal"
import {
    useGetContactsQuery,
    useCreateContactMutation,
    useUpdateContactMutation,
    useDeleteContactMutation,
} from "@/api/rtk/contacts-api"
import { useGetTeamsQuery } from "@/api/rtk/teams-api"
import { useAuthToken } from "@/hooks/use-auth-token"
import { useGetProfileQuery } from "@/api/auth"
import { KPICard } from "@/components/ui/kpi-card"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Loading } from "@/components/ui/loading"
import { NoDataFound } from "@/components/ui/no-data-found"
import { BulkStageTransferModal } from "@/components/ui/bulk-stage-transfer-modal"
import { ReactSelect } from "@/components/ui/react-select"
import { formatTeamLabelForUi } from "@/lib/deal-display"

const STAGES = ['Prospecting', 'Proposal Sent', 'Qualified', 'Negotiation', 'Closed Lost', 'Closed Won']
const AVATAR_COLORS = ['#6C63FF', '#22C55E', '#F59E0B', '#FF6B6B', '#8B83FF', '#FF8C42', '#059669', '#DC2626', '#7C3AED', '#0EA5E9']
const PAGE_SIZE_OPTIONS = [10, 25, 50, 100]

const STAGE_FILTER_OPTIONS = STAGES.map((s) => ({ value: s, label: s }))

const PAGE_SIZE_SELECT_OPTIONS = PAGE_SIZE_OPTIONS.map((n) => ({
    value: n.toString(),
    label: n.toString(),
}))

export default function ContactPage() {
    const { token } = useAuthToken()
    const searchParams = useSearchParams()
    const { page, setPage, limit, setLimit } = useUrlPagination(10)
    
    const [search, setSearch] = React.useState(searchParams.get("search") || "")
    const [stageFilter, setStageFilter] = React.useState(searchParams.get("stage") || "all")
    const [teamFilter, setTeamFilter] = React.useState(searchParams.get("team") || "all")
    const [sortCol, setSortCol] = React.useState(searchParams.get("sort") || "name")
    const [sortDir, setSortDir] = React.useState(parseInt(searchParams.get("dir") || "1", 10))

    const [selectedContact, setSelectedContact] = React.useState<Contact | null>(null)
    const [isDetailOpen, setIsDetailOpen] = React.useState(false)
    const [isAddOpen, setIsAddOpen] = React.useState(false)
    const [isEditOpen, setIsEditOpen] = React.useState(false)
    const [selectedIds, setSelectedIds] = React.useState<Set<string>>(new Set())
    const [isStageTransferOpen, setIsStageTransferOpen] = React.useState(false)

    const limitNum = Math.max(10, limit ?? 10)

    const { data: contactsResponse, isLoading } = useGetContactsQuery(
        { page, limit: limitNum, search: search?.trim() || undefined },
        {
            skip: !token,
            refetchOnMountOrArgChange: true
        }
    )
    const contacts = contactsResponse?.data ?? []
    const totalContacts = contactsResponse?.total ?? 0
    const totalPages = Math.max(1, Math.ceil(totalContacts / limitNum))

    const [createContact, { isLoading: isCreating }] = useCreateContactMutation()
    const [updateContact, { isLoading: isUpdating }] = useUpdateContactMutation()
    const [deleteContact] = useDeleteContactMutation()
    const { data: teams } = useGetTeamsQuery(undefined, { skip: !token })

    const filterTriggerClass =
        "h-10 px-3.5 rounded-xl w-full text-[13px] font-bold font-['Lexend_Deca'] border-border/80 bg-white shadow-sm hover:border-accent transition-all ring-0 focus:ring-0"
    const filterContentClass = "rounded-2xl border-border/40 shadow-premium"

    const teamFilterOptions = React.useMemo(
        () => [
            { value: "all", label: "All Teams" },
            ...(teams?.map((t: { id: string; name: string }) => ({
                value: t.name.toLowerCase().replace(/\s+/g, "-"),
                label: formatTeamLabelForUi(t.name),
            })) ?? []),
        ],
        [teams],
    )

    const stageFilterOptions = React.useMemo(
        () => [
            { value: "all", label: "All Stages" },
            ...STAGES.map((s) => ({ value: s, label: s })),
        ],
        [],
    )

    const pageSizeOptions = React.useMemo(
        () =>
            PAGE_SIZE_OPTIONS.map((n) => ({
                value: n.toString(),
                label: String(n),
            })),
        [],
    )
    const { data: profile } = useGetProfileQuery(undefined, { skip: !token })

    // Client-side stage/team filter on top of server-side search
    const filteredContacts = contacts.filter(c =>
        (stageFilter === "all" || c.stage === stageFilter) &&
        (teamFilter === "all" || c.team === teamFilter)
    )

    const canMutateContacts = Boolean(token)
    const canCreate = canMutateContacts
    const canUpdate = canMutateContacts
    const canDelete = canMutateContacts

    const sortedContacts = [...filteredContacts].sort((a: any, b: any) => {
        let av = a[sortCol]
        let bv = b[sortCol]
        if (typeof av === "string") { av = av.toLowerCase(); bv = bv?.toLowerCase() }
        return av < bv ? -sortDir : av > bv ? sortDir : 0
    })

    const stats: ContactStats = {
        totalContacts,
        hotLeads: contacts.filter(c => c.status === "Hot").length,
        closedWon: contacts.filter(c => c.status === "Won").length,
        pipelineValue: contacts.reduce((s, c) => s + (c.dealValue ?? 0), 0),
        avgDealSize: contacts.length ? Math.round(contacts.reduce((s, c) => s + (c.dealValue ?? 0), 0) / contacts.length) : 0,
    }

    const fmtUSD = (n: number) => n >= 1000 ? `$${(n / 1000).toFixed(1)}M` : `$${n}K`

    const handleOpenContact = (contact: Contact) => {
        setSelectedContact(contact)
        setIsDetailOpen(true)
    }

    const handleEditContact = (contact: Contact) => {
        setSelectedContact(contact)
        setIsEditOpen(true)
    }

    const handleDeleteContact = async (id: string | number) => {
        if (!confirm("Delete this contact?")) return
        try {
            await deleteContact(String(id)).unwrap()
            toast.success("Contact deleted")
        } catch {
            toast.error("Failed to delete contact")
        }
    }

    const handleCreateContact = async (data: Partial<Contact>) => {
        const nameParts = data.name?.split(" ") ?? []
        const initials = nameParts.map(n => n[0]).join("").toUpperCase().slice(0, 2) || "??"
        const userInitials = profile?.name?.split(" ").map((n: string) => n[0]).join("").toUpperCase() || "JD"
        try {
            await createContact({
                name: data.name!,
                initials,
                company: data.company ?? "",
                title: data.title ?? "",
                email: data.email!,
                website: data.website,
                phone: data.phone,
                stage: data.stage ?? "Prospecting",
                dealValue: data.dealValue ?? 0,
                rep: profile?.name ?? "Sales Rep",
                repAv: userInitials,
                team: data.team ?? "alpha",
                lastActivity: "Contact created",
                daysAgo: 0,
                status: "Active",
                color: AVATAR_COLORS[Math.floor(Math.random() * AVATAR_COLORS.length)],
                city: data.city,
                address: data.address,
                state: data.state,
                country: data.country,
                zipCode: data.zipCode,
                defaultLanguage: data.defaultLanguage ?? "English",
                description: data.description,
            }).unwrap()
            toast.success(`Contact ${data.name} added`)
            setIsAddOpen(false)
        } catch {
            toast.error("Failed to add contact")
        }
    }

    const handleUpdateContact = async (id: string, data: Partial<Contact>) => {
        try {
            await updateContact({ id, body: data }).unwrap()
            toast.success(`Contact updated`)
            setIsEditOpen(false)
            setSelectedContact(null)
        } catch {
            toast.error("Failed to update contact")
        }
    }

    const handleSelectId = (id: string, checked: boolean) => {
        setSelectedIds(prev => {
            const next = new Set(prev)
            checked ? next.add(id) : next.delete(id)
            return next
        })
    }

    const handleSelectAll = (checked: boolean) => {
        setSelectedIds(checked ? new Set(sortedContacts.map(c => c.id)) : new Set())
    }

    const handleBulkDelete = async () => {
        if (!confirm(`Delete ${selectedIds.size} selected contact${selectedIds.size > 1 ? "s" : ""}?`)) return
        const ids = [...selectedIds]
        let failed = 0
        await Promise.all(ids.map(id =>
            deleteContact(id).unwrap().catch(() => { failed++ })
        ))
        setSelectedIds(new Set())
        if (failed === 0) toast.success(`${ids.length} contact${ids.length > 1 ? "s" : ""} deleted`)
        else toast.error(`${failed} deletion${failed > 1 ? "s" : ""} failed`)
    }

    const handleBulkStageTransfer = async (_stageId: string, stageName: string) => {
        const ids = [...selectedIds]
        let failed = 0
        await Promise.all(ids.map(id =>
            updateContact({ id, body: { stage: stageName } }).unwrap().catch(() => { failed++ })
        ))
        setSelectedIds(new Set())
        if (failed === 0) toast.success(`${ids.length} contact${ids.length > 1 ? "s" : ""} moved to "${stageName}"`)
        else toast.error(`${failed} transfer${failed > 1 ? "s" : ""} failed`)
    }

    // Build stage options for the transfer modal (from STAGES constant + any stages already in data)
    const contactStageOptions = React.useMemo(() => {
        const seen = new Set<string>()
        const opts: { id: string; name: string; color: string }[] = []
        const stageColorMap: Record<string, string> = {
            'Prospecting': '#6C63FF', 'Qualified': '#8B83FF', 'Proposal Sent': '#F59E0B',
            'Negotiation': '#FF8C42', 'Closed Won': '#22C55E', 'Closed Lost': '#FF6B6B',
        }
        STAGES.forEach(s => {
            if (!seen.has(s)) {
                seen.add(s)
                opts.push({ id: s, name: s, color: stageColorMap[s] || '#6C63FF' })
            }
        })
        contacts.forEach(c => {
            if (c.stage && !seen.has(c.stage)) {
                seen.add(c.stage)
                opts.push({ id: c.stage, name: c.stage, color: stageColorMap[c.stage] || '#6C63FF' })
            }
        })
        return opts
    }, [contacts])

    const selectedContacts = React.useMemo(() => 
        contacts.filter(c => selectedIds.has(c.id)).map(c => ({
            id: c.id,
            name: c.name,
            currentStage: c.stage,
            subtext: c.company
        })), [contacts, selectedIds])

    const sharedStageId = React.useMemo(() => {
        if (selectedIds.size === 0) return undefined
        const idList = Array.from(selectedIds)
        const firstContact = contacts.find(c => c.id === idList[0])
        if (!firstContact) return undefined
        const allSame = idList.every(id => {
            const c = contacts.find(contact => contact.id === id)
            return c && c.stage === firstContact.stage
        })
        return allSame ? firstContact.stage : undefined
    }, [selectedIds, contacts])

    return (
        <div className="flex flex-col h-full gap-4.5 p-1 sm:p-2 md:p-4 animate-in fade-in duration-500 overflow-y-auto scrollbar-themed">
            {/* Header */}
            <div className="flex flex-col gap-4 rounded-2xl border border-white/40 bg-white/50 dark:bg-white/10 backdrop-blur-[15px] shadow-[0px_2px_20px_0px_rgba(0,0,0,0.06)] p-4 md:p-6">
                <div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
                    <div className="flex flex-col shrink-0">
                        <h1 className="text-[25px] md:text-[28px] font-extrabold text-text font-['Lexend'] tracking-tight leading-none">
                            Contacts
                        </h1>
                        <div className="flex items-center gap-2 mt-2">
                            <span className="text-[12px] font-bold text-text/80 bg-accent/5 px-2 py-0.5 rounded-md border border-accent/10">{totalContacts} Total</span>
                            <span className="text-[12px] font-bold text-accent/90 bg-accent/5 px-2 py-0.5 rounded-md border border-accent/10">Page {page} of {totalPages}</span>
                        </div>
                    </div>

                    <div className="flex items-center gap-3 w-full md:w-auto">
                        {canCreate && (
                            <Button
                                variant="tasksHeaderCta"
                                onClick={() => setIsAddOpen(true)}
                            >
                                <Plus size={18} className="stroke-[2px]" /> Add Contact
                            </Button>
                        )}
                    </div>
                </div>

                <div className="grid grid-cols-2 lg:flex lg:flex-row items-stretch lg:items-center gap-3 w-full pt-1 border-t border-border/10">
                    <div className="relative col-span-2 lg:flex-1 group">
                        <Search size={14} className="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400 group-focus-within:text-accent transition-colors duration-300 pointer-events-none" />
                        <Input
                            type="search"
                            placeholder="Search contacts..."
                            className="pl-10 pr-4 h-10 text-[13px] font-bold bg-white border-border/80 rounded-xl w-full font-['Lexend_Deca'] shadow-sm focus:ring-accent/20 focus:border-accent hover:border-accent/40 transition-all placeholder:text-gray-400"
                            value={search || ""}
                            onChange={(e) => { setSearch(e.target.value); setPage(1) }}
                        />
                    </div>

                    <div className="col-span-1">
                        <ReactSelect
                            value={teamFilter || "all"}
                            onValueChange={setTeamFilter}
                            options={teamFilterOptions}
                            placeholder="All Teams"
                            triggerClassName={filterTriggerClass}
                            contentClassName={filterContentClass}
                        />
                    </div>

                    <div className="col-span-1">
                        <ReactSelect
                            value={stageFilter || "all"}
                            onValueChange={setStageFilter}
                            options={stageFilterOptions}
                            placeholder="All Stages"
                            triggerClassName={filterTriggerClass}
                            contentClassName={filterContentClass}
                        />
                    </div>
                </div>
            </div>

            {/* KPI Strip */}
            <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-3.5 mb-1.5 h-auto overflow-visible">
                <KPICard label="Total Contacts" value={stats.totalContacts.toString()} subtext="In Pipeline" icon={<Users size={16} />} className="bg-white/50 border-white/40 md:py-4" />
                <KPICard label="Hot Leads" value={stats.hotLeads.toString()} subtext="Active Pursuit" icon={<Flame size={16} />} className="bg-white/50 border-white/40 md:py-4" />
                <KPICard label="Closed Won" value={stats.closedWon.toString()} subtext="Converted" icon={<CheckCircle2 size={16} />} className="bg-white/50 border-white/40 md:py-4" />
                <KPICard label="Pipeline Value" value={fmtUSD(stats.pipelineValue)} subtext="Across Contacts" icon={<DollarSign size={16} />} className="bg-white/50 border-white/40 md:py-4" />
                <KPICard label="Avg Deal Size" value={fmtUSD(stats.avgDealSize)} subtext="Per Contact" icon={<Target size={16} />} className="bg-white/50 border-white/40 md:py-4" />
            </div>

            {/* Main Content */}
            <div className="flex-1 min-h-0">
                <div className="pr-1 pb-4">
                    {isLoading ? (
                        <Loading message="Loading contacts..." className="h-64" />
                    ) : sortedContacts.length > 0 ? (
                        <>
                            {/* Bulk action bar */}
                            {selectedIds.size > 0 && (
                                <div className="flex items-center justify-between gap-3 mb-3 px-4 py-2.5 rounded-xl bg-accent/10 border border-accent/20">
                                    <span className="text-[13px] font-bold text-accent font-['Lexend']">
                                        {selectedIds.size} contact{selectedIds.size > 1 ? "s" : ""} selected
                                    </span>
                                    <div className="flex items-center gap-2">
                                        <Button
                                            variant="outlineToolbarClear"
                                            onClick={() => setSelectedIds(new Set())}
                                        >
                                            Clear
                                        </Button>
                                        {canUpdate && (
                                            <Button
                                                variant="outlineAccentInline"
                                                onClick={() => setIsStageTransferOpen(true)}
                                            >
                                                <ArrowRightLeft size={13} /> Move Stage
                                            </Button>
                                        )}
                                        {canDelete && (
                                            <Button
                                                variant="destructiveCompact"
                                                onClick={handleBulkDelete}
                                            >
                                                <Trash2 size={13} /> Delete {selectedIds.size}
                                            </Button>
                                        )}
                                    </div>
                                </div>
                            )}
                            <ContactListView
                                contacts={sortedContacts}
                                onOpen={handleOpenContact}
                                onEdit={handleEditContact}
                                onDelete={handleDeleteContact}
                                sortCol={sortCol || "name"}
                                sortDir={sortDir as 1 | -1}
                                onSort={(col) => {
                                    if (sortCol === col) setSortDir(sortDir === 1 ? -1 : 1)
                                    else { setSortCol(col); setSortDir(1) }
                                    setPage(1)
                                }}
                                selectedIds={selectedIds}
                                onSelectId={handleSelectId}
                                onSelectAll={handleSelectAll}
                                canUpdate={canUpdate}
                                canDelete={canDelete}
                            />
                            {totalPages > 1 && (
                                <div className="flex items-center justify-between gap-4 py-3 border-t border-border/40 mt-4">
                                    <div className="flex items-center gap-3">
                                        <p className="text-[12px] text-gray-600 font-['Lexend_Deca']">
                                            Showing {(page - 1) * limitNum + 1}–{Math.min(page * limitNum, totalContacts)} of {totalContacts}
                                        </p>
                                        <div className="flex items-center gap-2">
                                            <span className="text-[11px] text-gray-500 font-['Lexend_Deca']">Per page:</span>
                                            <ReactSelect
                                                value={limitNum.toString()}
                                                onValueChange={(v) => {
                                                    setLimit(parseInt(v))
                                                    setPage(1)
                                                }}
                                                options={pageSizeOptions}
                                                triggerClassName="h-8 w-[70px] text-[12px] border-gray-200"
                                            />
                                        </div>
                                    </div>
                                    <div className="flex items-center gap-2">
                                        <Button variant="outline" size="pagination" onClick={() => setPage(Math.max(1, page - 1))} disabled={page <= 1}>
                                            Previous
                                        </Button>
                                        <span className="text-[12px] font-semibold px-2">Page {page} of {totalPages}</span>
                                        <Button variant="outline" size="pagination" onClick={() => setPage(Math.min(totalPages, page + 1))} disabled={page >= totalPages}>
                                            Next
                                        </Button>
                                    </div>
                                </div>
                            )}
                        </>
                    ) : (
                        <NoDataFound
                            message="No contacts found"
                            description={search ? `No contacts match "${search}". Try a different search.` : "Add your first contact to get started."}
                        />
                    )}
                </div>
            </div>

            <ContactDetailModal
                contact={selectedContact}
                isOpen={isDetailOpen}
                onClose={() => setIsDetailOpen(false)}
                onEdit={() => { setIsDetailOpen(false); setIsEditOpen(true) }}
                onSendEmail={(email) => { toast.success(`Email sent to ${email}`); setIsDetailOpen(false) }}
                canUpdate={canUpdate}
            />
            <AddContactModal
                isOpen={isAddOpen}
                onClose={() => setIsAddOpen(false)}
                onCreate={handleCreateContact}
                teams={teams}
            />
            <EditContactModal
                contact={selectedContact}
                isOpen={isEditOpen}
                onClose={() => { setIsEditOpen(false); setSelectedContact(null) }}
                onUpdate={handleUpdateContact}
                teams={teams}
                canUpdate={canUpdate}
            />
            <BulkStageTransferModal
                open={isStageTransferOpen}
                onClose={() => setIsStageTransferOpen(false)}
                extraStages={contactStageOptions}
                selectedCount={selectedIds.size}
                entityLabel="contact"
                items={selectedContacts}
                currentStageId={sharedStageId}
                onRemoveItem={(id) => handleSelectId(id, false)}
                onTransfer={handleBulkStageTransfer}
            />
        </div>
    )
}
