import { useEffect, useState, useCallback } from 'react'
import { useSearchParams } from 'react-router-dom'
import { Plus, Ticket, AlertTriangle } from 'lucide-react'
import axios from 'axios'
import { TicketFilterBar } from '@/components/tickets/TicketFilterBar'
import { TicketListRow } from '@/components/tickets/TicketListRow'
import { TicketDetailPanel } from '@/components/tickets/TicketDetailPanel'
import { NewTicketModal } from '@/components/tickets/NewTicketModal'
import { integrationsApi } from '@/api/integrations'
import { ticketsApi } from '@/api/tickets'
import type { PSATicketSearchResult, PSABoard, PSATicketStatusItem } from '@/types/integrations'
import type { TicketFilters, PSAPriority } from '@/types/tickets'
import { DEFAULT_TICKET_FILTERS } from '@/types/tickets'

const PAGE_SIZE = 25

function filtersFromParams(params: URLSearchParams): TicketFilters & { page: number } {
  const assigned = params.get('assigned') ?? 'all'
  return {
    ...DEFAULT_TICKET_FILTERS,
    search: params.get('search') ?? '',
    board_id: params.get('board') ? Number(params.get('board')) : null,
    status_id: params.get('status') ? Number(params.get('status')) : null,
    priority: params.get('priority') ?? null,
    company_id: params.get('company') ? Number(params.get('company')) : null,
    assigned: (assigned === 'me' || assigned === 'unassigned' || assigned === 'all')
      ? assigned
      : Number(assigned),
    include_closed: params.get('closed') === 'true',
    page: params.get('page') ? Number(params.get('page')) : 1,
  }
}

export default function TicketsPage() {
  const [searchParams, setSearchParams] = useSearchParams()
  const { page, ...filters } = filtersFromParams(searchParams)

  const [tickets, setTickets] = useState<PSATicketSearchResult[]>([])
  const [total, setTotal] = useState(0)
  const [loading, setLoading] = useState(false)
  const [psaError, setPsaError] = useState<string | null>(null)
  const [boards, setBoards] = useState<PSABoard[]>([])
  const [statuses, setStatuses] = useState<PSATicketStatusItem[]>([])
  const [priorities, setPriorities] = useState<PSAPriority[]>([])
  const [members, setMembers] = useState<{ id: number; name: string }[]>([])
  const [selectedTicket, setSelectedTicket] = useState<PSATicketSearchResult | null>(null)
  const [showNewTicket, setShowNewTicket] = useState(false)

  // Load filter option data once
  useEffect(() => {
    integrationsApi.listBoards().then(setBoards).catch(() => {})
    ticketsApi.listPriorities().then(setPriorities).catch(() => {})
    integrationsApi.listMembers()
      .then(ms => setMembers(ms.map(m => ({ id: Number(m.id), name: m.name }))))
      .catch(() => {})
  }, [])

  // Load statuses when board changes
  useEffect(() => {
    if (filters.board_id) {
      integrationsApi.getBoardStatuses(filters.board_id)
        .then(setStatuses).catch(() => {})
    } else {
      setStatuses([])
    }
  }, [filters.board_id])

  // Fetch tickets on filter/page change
  const fetchTickets = useCallback(async () => {
    setLoading(true)
    setPsaError(null)
    try {
      const result = await ticketsApi.searchTickets({
        query: filters.search || undefined,
        board_id: filters.board_id ?? undefined,
        status_id: filters.status_id ?? undefined,
        include_closed: filters.include_closed,
        assigned_to_me: filters.assigned === 'me',
        unassigned: filters.assigned === 'unassigned',
        priority: filters.priority ?? undefined,
        company_id: filters.company_id ?? undefined,
        page,
        page_size: PAGE_SIZE,
      })
      setTickets(result.items)
      setTotal(result.total)
      // If the boards API returned empty (CW permissions), derive available boards from ticket data
      setBoards(prev => {
        if (prev.length > 0) return prev
        const seen = new Map<number, string>()
        result.items.forEach(t => {
          if (t.board_id && t.board_name) seen.set(t.board_id, t.board_name)
        })
        return seen.size > 0 ? Array.from(seen, ([id, name]) => ({ id, name })) : prev
      })
    } catch (err: unknown) {
      setTickets([])
      setTotal(0)
      if (axios.isAxiosError(err)) {
        const status = err.response?.status
        const detail = (err.response?.data as { detail?: string })?.detail ?? ''
        if (status === 502 && detail.toLowerCase().includes('permission')) {
          setPsaError('ConnectWise returned a permissions error. Check that the API member\'s security role has Service Tickets → Inquire → ALL and System → Table Setup → Inquire → ALL.')
        } else if (status === 502) {
          setPsaError('ConnectWise is unavailable or returned an error. Check your integration settings.')
        } else {
          setPsaError('Failed to load tickets.')
        }
      }
    } finally {
      setLoading(false)
    }
  }, [filters.search, filters.board_id, filters.status_id, filters.include_closed,
      filters.assigned, filters.priority, filters.company_id, page])

  useEffect(() => { fetchTickets() }, [fetchTickets])

  function updateFilters(updated: Partial<TicketFilters>) {
    const next = new URLSearchParams(searchParams)
    if ('search' in updated) updated.search ? next.set('search', updated.search!) : next.delete('search')
    if ('board_id' in updated) updated.board_id ? next.set('board', String(updated.board_id)) : next.delete('board')
    if ('status_id' in updated) updated.status_id ? next.set('status', String(updated.status_id)) : next.delete('status')
    if ('priority' in updated) updated.priority ? next.set('priority', updated.priority!) : next.delete('priority')
    if ('company_id' in updated) updated.company_id ? next.set('company', String(updated.company_id)) : next.delete('company')
    if ('assigned' in updated) {
      const a = updated.assigned
      a === 'all' ? next.delete('assigned') : next.set('assigned', String(a))
    }
    if ('include_closed' in updated) updated.include_closed ? next.set('closed', 'true') : next.delete('closed')
    next.delete('page') // reset to 1 on filter change
    setSearchParams(next)
  }

  function updatePage(p: number) {
    const next = new URLSearchParams(searchParams)
    p === 1 ? next.delete('page') : next.set('page', String(p))
    setSearchParams(next)
  }

  return (
    <div className="flex flex-col h-full overflow-hidden">
      {/* Header */}
      <div className="flex items-center justify-between px-6 py-4 border-b border-default shrink-0">
        <div className="flex items-center gap-2">
          <Ticket className="w-5 h-5 text-muted-foreground" />
          <h1 className="font-heading text-xl font-bold text-heading">Tickets</h1>
        </div>
        <button
          onClick={() => setShowNewTicket(true)}
          className="flex items-center gap-1.5 px-3 py-1.5 bg-accent text-white text-sm font-medium rounded-[5px] hover:bg-accent/90 transition-colors"
        >
          <Plus className="w-4 h-4" /> New Ticket
        </button>
      </div>

      {/* Filters */}
      <div className="px-6 py-3 border-b border-default shrink-0">
        <TicketFilterBar
          filters={filters}
          onChange={updateFilters}
          boards={boards}
          statuses={statuses}
          priorities={priorities}
          members={members}
          total={total}
          page={page}
          pageSize={PAGE_SIZE}
          onPageChange={updatePage}
          loading={loading}
        />
      </div>

      {/* List + Detail Panel */}
      <div className="flex flex-1 overflow-hidden">
        {/* Ticket list */}
        <div className={`flex flex-col overflow-y-auto transition-all ${selectedTicket ? 'w-1/2' : 'w-full'}`}>
          {loading && tickets.length === 0 && (
            <div className="flex items-center justify-center py-16 text-muted-foreground text-sm">
              Loading tickets…
            </div>
          )}
          {!loading && psaError && (
            <div className="mx-6 mt-6 flex items-start gap-3 px-4 py-3 rounded-lg bg-danger-dim border border-danger/30 text-sm text-danger">
              <AlertTriangle className="w-4 h-4 mt-0.5 shrink-0" />
              <span>{psaError}</span>
            </div>
          )}
          {!loading && !psaError && tickets.length === 0 && (
            <div className="flex flex-col items-center justify-center py-16 text-muted-foreground text-sm gap-2">
              <Ticket className="w-8 h-8 opacity-30" />
              No tickets match your filters
            </div>
          )}
          {tickets.map(t => (
            <TicketListRow
              key={t.id}
              ticket={t}
              selected={selectedTicket?.id === t.id}
              onClick={() => setSelectedTicket(t)}
            />
          ))}
        </div>

        {/* Detail panel */}
        {selectedTicket && (
          <div className="w-1/2 border-l border-default overflow-y-auto">
            <TicketDetailPanel
              ticket={selectedTicket}
              onClose={() => setSelectedTicket(null)}
              onStatusUpdated={(ticketId, newStatus) => {
                setTickets(prev => prev.map(t =>
                  t.id === String(ticketId) ? { ...t, status_name: newStatus } : t
                ))
              }}
            />
          </div>
        )}
      </div>

      {/* New Ticket Modal */}
      {showNewTicket && (
        <NewTicketModal
          defaultTab="quick"
          onClose={() => setShowNewTicket(false)}
          onCreated={() => { setShowNewTicket(false); fetchTickets() }}
        />
      )}
    </div>
  )
}
