'use client'

import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
import type { AcquisitionSummary, AppUser, LeadRecord, Prospect, SearchParams, OutreachConfig, SearchState, ScrapeProgress, TeamUserRecord } from '@/lib/types'
import { signOut } from '@/lib/auth/client'
import { fetchProspectMatches, fetchVisibleLeads, fetchVisibleUsers, persistLead } from '@/lib/leads/api'
import { buildProspectMatchInfo } from '@/lib/leads/matching'
import { hasUserManagementAccess } from '@/lib/auth/roles'
import { runSearch } from '@/lib/sources/adapter'
import { processProspects } from '@/lib/pipeline/process'
import { exportLeadsCSV, downloadCSV } from '@/lib/export/csvExport'
import { scrapeProspectsFromUrl } from '@/lib/urlScrape'
import Sidebar from '@/components/layout/Sidebar'
import TopBar from '@/components/layout/TopBar'
import SearchPanel from '@/components/search/SearchPanel'
import ProspectsTable from '@/components/table/ProspectsTable'
import KPIStrip from '@/components/table/KPIStrip'
import LeadDetailPanel from '@/components/detail/LeadDetailPanel'
import OutreachComposer from '@/components/outreach/OutreachComposer'
import ExportCenter from '@/components/export/ExportCenter'
import LeadLibraryView from '@/components/library/LeadLibraryView'
import PerformanceView from '@/components/performance/PerformanceView'
import TeamManagementView from '@/components/team/TeamManagementView'

type Page = 'dashboard' | 'library' | 'outreach' | 'export' | 'team' | 'performance'

const DEFAULT_CONFIG: OutreachConfig = {
  sender_name: 'Mspacez Partnerships Team',
  sender_role: 'Business Development',
  sender_company: 'Mspacez',
  offer_title: 'Virtual Office Partner Program',
  commission_percent: 10,
  client_discount_percent: 10,
  exclusivity_text: 'Early partners receive priority branch access and a dedicated account manager.',
  cta_text: 'Would you be open to a quick 10-minute call to walk through the details?',
  cta_contact: '',
  email_tone: 'Executive Professional',
  language: 'English',
  email_style: 'full',
}

interface ProspectingAppProps {
  user: AppUser
}

function applyMatchToProspect(prospect: Prospect, match: ReturnType<typeof buildProspectMatchInfo> | { lead_status: 'new' }) {
  return {
    ...prospect,
    lead_status: match.lead_status === 'new' ? prospect.lead_status : match.lead_status,
    matched_lead_id: 'matched_lead_id' in match ? match.matched_lead_id : undefined,
    matched_scope: 'matched_scope' in match ? match.matched_scope : undefined,
    matched_owner_name: 'matched_owner_name' in match ? match.matched_owner_name : undefined,
    matched_assigned_to: 'matched_assigned_to' in match ? match.matched_assigned_to : undefined,
    matched_assigned_name: 'matched_assigned_name' in match ? match.matched_assigned_name : undefined,
    matched_visibility_scope: 'matched_visibility_scope' in match ? match.matched_visibility_scope : undefined,
    matched_stage: 'matched_stage' in match ? match.matched_stage : undefined,
    matched_follow_up_at: 'matched_follow_up_at' in match ? match.matched_follow_up_at : undefined,
  }
}

export default function ProspectingApp({ user }: ProspectingAppProps) {
  const router = useRouter()
  const [activePage, setActivePage] = useState<Page>('dashboard')
  const [outreachMode, setOutreachMode] = useState<'search' | 'library'>('search')
  const [prospects, setProspects] = useState<Prospect[]>([])
  const [visibleLeads, setVisibleLeads] = useState<LeadRecord[]>([])
  const [teamUsers, setTeamUsers] = useState<TeamUserRecord[]>([])
  const [performanceRefreshToken, setPerformanceRefreshToken] = useState(0)
  const [searchState, setSearchState] = useState<SearchState>('idle')
  const [selectedProspect, setSelectedProspect] = useState<Prospect | null>(null)
  const [outreachConfig, setOutreachConfig] = useState<OutreachConfig>(DEFAULT_CONFIG)
  const [acquisitionSummary, setAcquisitionSummary] = useState<AcquisitionSummary | null>(null)
  const [errorMessage, setErrorMessage] = useState('')
  const [scrapeProgress, setScrapeProgress] = useState<ScrapeProgress | null>(null)

  useEffect(() => {
    void refreshSharedData().catch(() => {
      setErrorMessage('Shared lead history could not be loaded yet.')
    })
  }, [])

  const refreshVisibleLeads = async () => {
    const leads = await fetchVisibleLeads()
    setVisibleLeads(leads)
    return leads
  }

  const refreshTeamUsers = async () => {
    const users = await fetchVisibleUsers()
    setTeamUsers(users)
    return users
  }

  const refreshSharedData = async () => {
    const [leads, users] = await Promise.all([
      fetchVisibleLeads(),
      fetchVisibleUsers(),
    ])

    setVisibleLeads(leads)
    setTeamUsers(users)
    return { leads, users }
  }

  const mergeLeadRecord = (lead: LeadRecord) => {
    setVisibleLeads(prev => [lead, ...prev.filter(item => item.id !== lead.id)])
    void refreshTeamUsers().catch(() => {})
    setPerformanceRefreshToken(prev => prev + 1)
  }

  const handleLogout = async () => {
    await signOut()
    router.refresh()
  }

  const applyHistoricalStatus = async (raw: Prospect[]): Promise<Prospect[]> => {
    const matchMap = await fetchProspectMatches(raw)

    return raw.map(prospect => applyMatchToProspect(
      prospect,
      matchMap[prospect.id] ?? { lead_status: 'new' }
    ))
  }

  const handleSearch = async (params: SearchParams) => {
    setSearchState('searching')
    setOutreachMode('search')
    setErrorMessage('')
    setAcquisitionSummary(null)
    setScrapeProgress(null)

    try {
      const response = await runSearch(params)
      setAcquisitionSummary(response.summary)
      setSearchState('processing')
      await new Promise(resolve => setTimeout(resolve, 150))
      const processed = processProspects(response.results)
      const withHistory = await applyHistoricalStatus(processed)
      setProspects(withHistory)
      setSearchState(withHistory.length === 0 ? 'no_results' : 'results_loaded')
      setSelectedProspect(null)
    } catch (err) {
      setSearchState('search_error')
      setErrorMessage(err instanceof Error ? err.message : 'Search failed. Please try again.')
    }
  }

  const handleUrlScrape = async (url: string, maxResults: number, _progress: (p: ScrapeProgress) => void) => {
    setSearchState('searching')
    setOutreachMode('search')
    setErrorMessage('')
    setAcquisitionSummary(null)

    try {
      const data = await scrapeProspectsFromUrl(url, maxResults, setScrapeProgress)
      const rawResults = data.results || []
      setAcquisitionSummary(data.summary)

      setSearchState('processing')
      await new Promise(resolve => setTimeout(resolve, 150))

      const processed = processProspects(rawResults)
      const withHistory = await applyHistoricalStatus(processed)

      const skipped = rawResults.length - withHistory.filter(p => p.lead_status === 'new').length

      setScrapeProgress({
        status: 'done',
        message: data.summary.description,
        found: rawResults.length,
        processed: withHistory.length,
        skipped_duplicates: Math.max(0, skipped),
        source_type: data.summary.detected_source_type as ScrapeProgress['source_type'],
      })

      setProspects(withHistory)
      setSearchState(withHistory.length === 0 ? 'no_results' : 'results_loaded')
      setSelectedProspect(null)
    } catch {
      setScrapeProgress({
        status: 'error',
        message: 'Connection error. Please try again.',
        found: 0,
        processed: 0,
        skipped_duplicates: 0,
      })
      setSearchState('search_error')
      setErrorMessage('URL scrape failed. Please try again.')
    }
  }

  const syncProspectFromLead = (prospectId: string, lead: LeadRecord) => {
    const match = buildProspectMatchInfo(lead, user.id)
    setProspects(prev => prev.map(item => item.id === prospectId ? applyMatchToProspect(item, match) : item))
    setSelectedProspect(prev => prev?.id === prospectId ? applyMatchToProspect(prev, match) : prev)
  }

  const handleLeadUpdated = (lead: LeadRecord) => {
    mergeLeadRecord(lead)

    setProspects(prev => prev.map(item => {
      if (item.matched_lead_id !== lead.id) return item
      return applyMatchToProspect(item, buildProspectMatchInfo(lead, user.id))
    }))
    setSelectedProspect(prev => {
      if (!prev || prev.matched_lead_id !== lead.id) return prev
      return applyMatchToProspect(prev, buildProspectMatchInfo(lead, user.id))
    })
  }

  const handleSaveLead = async (prospect: Prospect) => {
    try {
      const lead = await persistLead(prospect, 'saved')
      handleLeadUpdated(lead)
      syncProspectFromLead(prospect.id, lead)
    } catch {
      setErrorMessage('Lead save failed. Please try again.')
    }
  }

  const handleExcludeLead = async (prospect: Prospect) => {
    try {
      const lead = await persistLead(prospect, 'excluded')
      handleLeadUpdated(lead)
      syncProspectFromLead(prospect.id, lead)
    } catch {
      setErrorMessage('Lead update failed. Please try again.')
    }
  }

  const handleExportLeads = () => {
    const exportTargets = activePage === 'library'
      ? visibleLeads.map(lead => lead.full_data)
      : prospects

    if (exportTargets.length === 0) return
    const csv = exportLeadsCSV(exportTargets)
    downloadCSV(csv, `mspacez-leads-${new Date().toISOString().slice(0, 10)}.csv`)
  }

  const libraryProspects = visibleLeads.map(lead => applyMatchToProspect(
    lead.full_data,
    buildProspectMatchInfo(lead, user.id)
  ))

  const outreachProspects = outreachMode === 'library'
    ? libraryProspects
    : prospects.length > 0
      ? prospects
      : libraryProspects

  const handleGenerateOutreach = () => {
    setOutreachMode(activePage === 'library' ? 'library' : 'search')
    setActivePage('outreach')
  }

  const PAGE_TITLES: Record<Page, { title: string; subtitle: string }> = {
    dashboard: {
      title: 'Partner Prospecting Dashboard',
      subtitle: 'Search, qualify, and score high-value business leads for Virtual Office partnership outreach.',
    },
    library: {
      title: 'Lead Library',
      subtitle: 'Track real saved leads, CRM stages, follow-ups, and activity history across the shared database.',
    },
    outreach: {
      title: 'Outreach Composer',
      subtitle: 'Configure your partnership offer and generate email-ready outreach content.',
    },
    export: {
      title: 'Export Center',
      subtitle: 'Export search-session files for action, and use admin-only JSON backup tools for full lead-library survivability.',
    },
    performance: {
      title: 'Performance & Deals',
      subtitle: 'Track contract outcomes, points, and leaderboard visibility across the live CRM.',
    },
    team: {
      title: 'Team Management',
      subtitle: 'Review user roles, ownership load, and assignment coverage across the shared CRM.',
    },
  }

  const { title, subtitle } = PAGE_TITLES[activePage]
  const summaryTone = acquisitionSummary?.mode === 'real'
    ? 'border-[#22c55e]/20 bg-[#22c55e]/10 text-[#9fe8c4]'
    : acquisitionSummary?.mode === 'mixed'
      ? 'border-[#ffb95f]/20 bg-[#ffb95f]/10 text-[#ffd59a]'
      : acquisitionSummary?.mode === 'unsupported'
        ? 'border-red-500/20 bg-red-500/10 text-red-300'
        : 'border-[#60a5fa]/20 bg-[#60a5fa]/10 text-[#bfdbfe]'

  return (
    <div className="flex h-screen overflow-hidden bg-[#0b1326] text-[#dae2fd]">
      <Sidebar activePage={activePage} onNavigate={setActivePage} showTeamPage={hasUserManagementAccess(user)} />

      <main className="flex-1 ml-64 flex flex-col h-screen overflow-hidden">
        <TopBar
          title={title}
          subtitle={subtitle}
          prospects={activePage === 'library' ? visibleLeads.map(lead => lead.full_data) : prospects}
          onExport={handleExportLeads}
          onGenerateOutreach={handleGenerateOutreach}
          user={user}
          onLogout={handleLogout}
        />

        {activePage === 'dashboard' && (
          <div className="flex flex-1 overflow-hidden">
            <SearchPanel
              onSearch={handleSearch}
              onUrlScrape={handleUrlScrape}
              isSearching={searchState === 'searching' || searchState === 'processing'}
              scrapeProgress={scrapeProgress}
            />

            <div className="flex-1 flex flex-col overflow-hidden">
              <KPIStrip prospects={prospects} searchState={searchState} />

              {acquisitionSummary && (
                <div className={`mx-6 mb-3 rounded-xl border p-4 ${summaryTone}`}>
                  <div className="flex flex-wrap items-center gap-2 mb-2">
                    <span className="text-[10px] font-black uppercase tracking-widest">{acquisitionSummary.title}</span>
                    <span className="text-[10px] opacity-70 uppercase tracking-widest">{acquisitionSummary.source_label}</span>
                    <span className="ml-auto text-[11px] opacity-80">
                      {acquisitionSummary.returned_results} returned / {acquisitionSummary.requested_results} requested
                    </span>
                  </div>
                  <p className="text-sm leading-relaxed mb-2">{acquisitionSummary.description}</p>
                  <div className="flex flex-wrap gap-2 text-[10px] font-black uppercase tracking-widest">
                    <span className="px-2 py-1 rounded-full bg-[#131b2e]/40">Real {acquisitionSummary.real_results}</span>
                    <span className="px-2 py-1 rounded-full bg-[#131b2e]/40">Demo {acquisitionSummary.demo_results}</span>
                    <span className="px-2 py-1 rounded-full bg-[#131b2e]/40">{acquisitionSummary.channel === 'search' ? 'Search Mode' : 'URL Ingestion'}</span>
                  </div>
                  {acquisitionSummary.warnings.length > 0 && (
                    <p className="text-[12px] mt-2 opacity-90">{acquisitionSummary.warnings[0]}</p>
                  )}
                </div>
              )}

              {searchState === 'search_error' && (
                <div className="mx-6 mb-3 p-3 bg-red-500/10 border border-red-500/20 rounded-xl flex items-center gap-2">
                  <span className="material-symbols-outlined text-red-400 text-lg">error</span>
                  <span className="text-sm text-red-300">{errorMessage}</span>
                </div>
              )}

              {searchState === 'no_results' && (
                <div className="mx-6 mb-3 p-3 bg-[#ffb95f]/10 border border-[#ffb95f]/20 rounded-xl flex items-center gap-2">
                  <span className="material-symbols-outlined text-[#ffb95f] text-lg">info</span>
                  <span className="text-sm text-[#ffb95f]">No results found for your search. Try different filters.</span>
                </div>
              )}

              <div className="flex-1 mx-6 mb-6 bg-[#060e20] rounded-xl overflow-hidden flex flex-col shadow-2xl">
                <ProspectsTable
                  prospects={prospects}
                  selectedId={selectedProspect?.id ?? null}
                  onSelect={prospect => setSelectedProspect(prev => prev?.id === prospect.id ? null : prospect)}
                  onSaveLead={handleSaveLead}
                  onExcludeLead={handleExcludeLead}
                />
              </div>
            </div>

            <LeadDetailPanel
              prospect={selectedProspect}
              outreachConfig={outreachConfig}
              onClose={() => setSelectedProspect(null)}
            />
          </div>
        )}

        {activePage === 'outreach' && (
          <div className="flex-1 overflow-hidden">
            <OutreachComposer
              prospects={outreachProspects}
              config={outreachConfig}
              currentUser={user}
              onConfigChange={setOutreachConfig}
              onLeadTracked={handleLeadUpdated}
            />
          </div>
        )}

        {activePage === 'library' && (
          <LeadLibraryView
            leads={visibleLeads}
            teamUsers={teamUsers}
            currentUser={user}
            outreachConfig={outreachConfig}
            onLeadUpdated={handleLeadUpdated}
            onLibraryReload={() => refreshSharedData().then(() => {})}
          />
        )}

        {activePage === 'performance' && (
          <PerformanceView
            currentUser={user}
            refreshToken={performanceRefreshToken}
          />
        )}

        {activePage === 'team' && (
          <TeamManagementView
            currentUser={user}
            users={teamUsers}
            leads={visibleLeads}
            onOpenLibrary={() => setActivePage('library')}
            onUsersChanged={refreshTeamUsers}
          />
        )}

        {activePage === 'export' && (
          <div className="flex-1 overflow-hidden">
            <ExportCenter
              prospects={prospects}
              visibleLeads={visibleLeads}
              config={outreachConfig}
              currentUser={user}
              onLibraryReload={() => refreshSharedData().then(() => {})}
            />
          </div>
        )}
      </main>
    </div>
  )
}
