import { useState } from 'react'
import { createFileRoute, useParams, useNavigate, Link } from '@tanstack/react-router'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { api } from '@/lib/api-client'
import { queryOptions } from '@tanstack/react-query'
import { identifierListOptions, identifierMutations, identifierKeys } from '@/api/identifiers'
import { enrollmentListOptions } from '@/api/lessons'
import { moduleListOptions } from '@/api/modules'
import { MemberForm } from '@/components/accounts/member-form'
import { IdentifierForm, type IdentifierFiles } from '@/components/accounts/identifier-form'
import { DataTable, type Column } from '@/components/shared/data-table'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'
import { Skeleton } from '@/components/ui/skeleton'
import { ArrowLeft, Plus, Trash2, CreditCard } from 'lucide-react'
import { toast } from 'sonner'
import { AvatarUpload } from '@/components/shared/avatar-upload'
import { useAuthStore } from '@/stores/auth.store'
import { cn } from '@/lib/utils'
import type { Member } from '@/types/account'
import type { Enrollment } from '@/types/lesson'

function memberDetailOptions(id: string) {
  return queryOptions({
    queryKey: ['members', 'detail', id],
    queryFn: () => api.get<Member>(`/v1/members/${id}`),
  })
}

export const Route = createFileRoute('/_authenticated/members/$memberId')({
  validateSearch: (search: Record<string, unknown>) => ({
    tab: (search.tab as string) || 'details',
  }),
  component: MemberDetailPage,
})

// ─── Identifier images ────────────────────────────────────────────────────────

function IdentifierImages({ identifierId }: { identifierId: string }) {
  const { data } = useQuery({
    queryKey: ['files', 'member_identifier', identifierId],
    queryFn: () => api.get<{ data: { id: string; path: string; category: string }[] }>('/v1/files', {
      entityType: 'member_identifier',
      entityId: identifierId,
    }),
  })
  const files = data?.data ?? []
  const frontFile = files.find((f) => f.category === 'front')
  const backFile = files.find((f) => f.category === 'back')
  if (!frontFile && !backFile) return null
  return (
    <div className="flex gap-2 mt-2">
      {frontFile && <img src={`/v1/files/serve/${frontFile.path}`} alt="Front" className="h-20 rounded border object-cover" />}
      {backFile && <img src={`/v1/files/serve/${backFile.path}`} alt="Back" className="h-20 rounded border object-cover" />}
    </div>
  )
}

const ID_TYPE_LABELS: Record<string, string> = {
  drivers_license: "Driver's License",
  passport: 'Passport',
  school_id: 'School ID',
}

function statusBadge(status: string) {
  const variants: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {
    active: 'default', paused: 'secondary', cancelled: 'destructive', completed: 'outline',
  }
  return <Badge variant={variants[status] ?? 'outline'}>{status}</Badge>
}

const enrollmentColumns: Column<Enrollment & { instructorName?: string; slotInfo?: string; lessonTypeName?: string }>[] = [
  { key: 'status', header: 'Status', sortable: true, render: (e) => statusBadge(e.status) },
  { key: 'instructor_name', header: 'Instructor', render: (e) => <>{e.instructorName ?? e.instructorId}</> },
  { key: 'slot_info', header: 'Day / Time', render: (e) => <>{e.slotInfo ?? '—'}</> },
  { key: 'lesson_type', header: 'Lesson', render: (e) => <>{e.lessonTypeName ?? '—'}</> },
  { key: 'start_date', header: 'Start', sortable: true, render: (e) => <>{new Date(e.startDate + 'T00:00:00').toLocaleDateString()}</> },
  { key: 'rate', header: 'Rate', render: (e) => <>{e.rate ? `$${e.rate} / ${e.billingInterval} ${e.billingUnit}` : <span className="text-muted-foreground">—</span>}</> },
]

// ─── Page ─────────────────────────────────────────────────────────────────────

function MemberDetailPage() {
  const { memberId } = useParams({ from: '/_authenticated/members/$memberId' })
  const search = Route.useSearch()
  const navigate = useNavigate()
  const queryClient = useQueryClient()
  const [addIdOpen, setAddIdOpen] = useState(false)
  const [createLoading, setCreateLoading] = useState(false)
  const tab = search.tab ?? 'details'

  const token = useAuthStore((s) => s.token)
  const hasPermission = useAuthStore((s) => s.hasPermission)

  const { data: member, isLoading } = useQuery(memberDetailOptions(memberId))
  const { data: idsData } = useQuery({ ...identifierListOptions(memberId), enabled: tab === 'identity' })
  const { data: modulesData } = useQuery(moduleListOptions())
  const lessonsEnabled = (modulesData?.data ?? []).some((m) => m.slug === 'lessons' && m.enabled && m.licensed)

  const { data: enrollmentsData } = useQuery({
    ...enrollmentListOptions({ memberId, page: 1, limit: 100, order: 'asc' }),
    enabled: tab === 'enrollments' && lessonsEnabled,
  })

  const updateMutation = useMutation({
    mutationFn: (data: Record<string, unknown>) => api.patch<Member>(`/v1/members/${memberId}`, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['members', 'detail', memberId] })
      toast.success('Member updated')
    },
    onError: (err) => toast.error(err instanceof Error ? err.message : 'Update failed'),
  })

  async function uploadIdFile(identifierId: string, file: File, category: string): Promise<string | null> {
    const formData = new FormData()
    formData.append('file', file)
    formData.append('entityType', 'member_identifier')
    formData.append('entityId', identifierId)
    formData.append('category', category)
    const res = await fetch('/v1/files', {
      method: 'POST',
      headers: { Authorization: `Bearer ${token}` },
      body: formData,
    })
    if (!res.ok) return null
    return (await res.json()).id
  }

  async function handleCreateIdentifier(data: Record<string, unknown>, files: IdentifierFiles) {
    setCreateLoading(true)
    try {
      const identifier = await identifierMutations.create(memberId, data)
      const updates: Record<string, unknown> = {}
      if (files.front) {
        const fileId = await uploadIdFile(identifier.id, files.front, 'front')
        if (fileId) updates.imageFrontFileId = fileId
      }
      if (files.back) {
        const fileId = await uploadIdFile(identifier.id, files.back, 'back')
        if (fileId) updates.imageBackFileId = fileId
      }
      if (Object.keys(updates).length > 0) await identifierMutations.update(identifier.id, updates)
      queryClient.invalidateQueries({ queryKey: identifierKeys.all(memberId) })
      toast.success('ID added')
      setAddIdOpen(false)
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to add ID')
    } finally {
      setCreateLoading(false)
    }
  }

  const deleteIdMutation = useMutation({
    mutationFn: identifierMutations.delete,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: identifierKeys.all(memberId) })
      toast.success('ID removed')
    },
    onError: (err) => toast.error(err.message),
  })

  function setTab(t: string) {
    navigate({ to: '/members/$memberId', params: { memberId }, search: { tab: t } })
  }

  if (isLoading) {
    return (
      <div className="space-y-4">
        <Skeleton className="h-8 w-48" />
        <Skeleton className="h-10 w-full" />
        <Skeleton className="h-64 w-full max-w-lg" />
      </div>
    )
  }

  if (!member) return <p className="text-muted-foreground">Member not found</p>

  const identifiers = idsData?.data ?? []

  const tabs = [
    { key: 'details', label: 'Details' },
    { key: 'identity', label: 'Identity Documents' },
    ...(lessonsEnabled ? [{ key: 'enrollments', label: 'Enrollments' }] : []),
  ]

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center gap-3">
        <Button variant="ghost" size="sm" onClick={() => navigate({ to: '/accounts/$accountId/members', params: { accountId: member.accountId }, search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
          <ArrowLeft className="h-4 w-4" />
        </Button>
        <div>
          <h1 className="text-2xl font-bold">{member.firstName} {member.lastName}</h1>
          <div className="flex items-center gap-2 text-sm text-muted-foreground">
            <span>#{member.memberNumber}</span>
            {member.isMinor && <Badge variant="secondary">Minor</Badge>}
            <Link to="/accounts/$accountId" params={{ accountId: member.accountId }} className="hover:underline">
              View Account
            </Link>
          </div>
        </div>
      </div>

      {/* Tabs */}
      <nav className="flex gap-1 border-b">
        {tabs.map((t) => (
          <button
            key={t.key}
            onClick={() => setTab(t.key)}
            className={cn(
              'px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors',
              tab === t.key
                ? 'border-primary text-foreground'
                : 'border-transparent text-muted-foreground hover:text-foreground hover:border-border',
            )}
          >
            {t.label}
          </button>
        ))}
      </nav>

      {/* Details tab */}
      {tab === 'details' && (
        <div className="max-w-lg space-y-4">
          <div className="flex items-center gap-4">
            <AvatarUpload entityType="member" entityId={memberId} size="lg" />
            <div>
              <p className="font-medium">{member.firstName} {member.lastName}</p>
              <p className="text-sm text-muted-foreground">{member.email ?? 'No email'}</p>
            </div>
          </div>
          <MemberForm
            accountId={member.accountId}
            defaultValues={member}
            onSubmit={(data) => updateMutation.mutate(data)}
            loading={updateMutation.isPending}
          />
        </div>
      )}

      {/* Identity Documents tab */}
      {tab === 'identity' && (
        <div className="space-y-4 max-w-2xl">
          <div className="flex items-center justify-between">
            <p className="text-sm text-muted-foreground">{identifiers.length} document(s) on file</p>
            <Dialog open={addIdOpen} onOpenChange={setAddIdOpen}>
              <DialogTrigger asChild>
                <Button size="sm"><Plus className="mr-2 h-4 w-4" />Add ID</Button>
              </DialogTrigger>
              <DialogContent>
                <DialogHeader><DialogTitle>Add Identity Document</DialogTitle></DialogHeader>
                <IdentifierForm memberId={memberId} onSubmit={handleCreateIdentifier} loading={createLoading} />
              </DialogContent>
            </Dialog>
          </div>
          {identifiers.length === 0 ? (
            <p className="text-sm text-muted-foreground py-8 text-center">No IDs on file</p>
          ) : (
            <div className="space-y-3">
              {identifiers.map((id) => (
                <div key={id.id} className="flex items-start justify-between p-3 rounded-md border">
                  <div className="flex items-start gap-3">
                    <CreditCard className="h-5 w-5 text-muted-foreground mt-0.5" />
                    <div className="space-y-1">
                      <div className="flex items-center gap-2">
                        <span className="font-medium">{ID_TYPE_LABELS[id.type] ?? id.type}</span>
                        {id.isPrimary && <Badge variant="secondary">Primary</Badge>}
                      </div>
                      <p className="text-sm font-mono text-muted-foreground">{id.value}</p>
                      {id.issuingAuthority && <p className="text-xs text-muted-foreground">{id.issuingAuthority}</p>}
                      <div className="flex gap-4 text-xs text-muted-foreground">
                        {id.issuedDate && <span>Issued: {id.issuedDate}</span>}
                        {id.expiresAt && <span>Expires: {id.expiresAt}</span>}
                      </div>
                      {(id.imageFrontFileId || id.imageBackFileId) && <IdentifierImages identifierId={id.id} />}
                    </div>
                  </div>
                  <Button variant="ghost" size="sm" onClick={() => deleteIdMutation.mutate(id.id)}>
                    <Trash2 className="h-4 w-4 text-destructive" />
                  </Button>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {/* Enrollments tab */}
      {tab === 'enrollments' && (
        <div className="space-y-4">
          <div className="flex items-center justify-between">
            <p className="text-sm text-muted-foreground">{enrollmentsData?.pagination.total ?? 0} enrollment(s)</p>
            {hasPermission('lessons.edit') && (
              <Button size="sm" onClick={() => navigate({ to: '/lessons/enrollments/new', search: { memberId, accountId: undefined } })}>
                <Plus className="h-4 w-4 mr-1" />Enroll
              </Button>
            )}
          </div>
          <DataTable
            columns={enrollmentColumns}
            data={enrollmentsData?.data ?? []}
            loading={!enrollmentsData && tab === 'enrollments'}
            page={1}
            totalPages={1}
            total={enrollmentsData?.data?.length ?? 0}
            onPageChange={() => {}}
            onSort={() => {}}
            onRowClick={(e) => navigate({ to: '/lessons/enrollments/$enrollmentId', params: { enrollmentId: e.id }, search: { tab: 'details' } })}
          />
        </div>
      )}
    </div>
  )
}
