import { useState } from 'react'
import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import {
  instructorListOptions, instructorMutations, instructorKeys,
  lessonTypeListOptions, lessonTypeMutations, lessonTypeKeys,
  gradingScaleListOptions, gradingScaleMutations, gradingScaleKeys,
  storeClosureListOptions, storeClosureMutations, storeClosureKeys,
} from '@/api/lessons'
import { usePagination } from '@/hooks/use-pagination'
import { DataTable, type Column } from '@/components/shared/data-table'
import { InstructorForm } from '@/components/lessons/instructor-form'
import { LessonTypeForm } from '@/components/lessons/lesson-type-form'
import { GradingScaleForm } from '@/components/lessons/grading-scale-form'
import { StoreClosureForm } from '@/components/lessons/store-closure-form'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Input } from '@/components/ui/input'
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'
import { Plus, Search, Trash2 } from 'lucide-react'
import { toast } from 'sonner'
import { useAuthStore } from '@/stores/auth.store'
import type { Instructor, LessonType, GradingScale, StoreClosure } from '@/types/lesson'

export const Route = createFileRoute('/_authenticated/lessons/schedule/')({
  validateSearch: (search: Record<string, unknown>) => ({
    tab: (search.tab as string) || 'instructors',
    page: Number(search.page) || 1,
    limit: Number(search.limit) || 25,
    q: (search.q as string) || undefined,
    sort: (search.sort as string) || undefined,
    order: (search.order as 'asc' | 'desc') || 'asc',
  }),
  component: ScheduleHubPage,
})

const TABS = [
  { key: 'instructors', label: 'Instructors' },
  { key: 'lesson-types', label: 'Lesson Types' },
  { key: 'grading-scales', label: 'Grading Scales' },
  { key: 'closures', label: 'Store Closures' },
]

function ScheduleHubPage() {
  const navigate = useNavigate()
  const search = Route.useSearch()
  const tab = search.tab
  const hasPermission = useAuthStore((s) => s.hasPermission)
  const canAdmin = hasPermission('lessons.admin')

  function setTab(t: string) {
    navigate({ to: '/lessons/schedule', search: { ...search, tab: t, page: 1 } })
  }

  return (
    <div className="space-y-6">
      <h1 className="text-2xl font-bold">Lessons Setup</h1>
      <div className="flex gap-1 border-b">
        {TABS.map((t) => (
          <button
            key={t.key}
            onClick={() => setTab(t.key)}
            className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
              tab === t.key
                ? 'border-primary text-primary'
                : 'border-transparent text-muted-foreground hover:text-foreground'
            }`}
          >
            {t.label}
          </button>
        ))}
      </div>

      {tab === 'instructors' && <InstructorsTab canAdmin={canAdmin} search={search} />}
      {tab === 'lesson-types' && <LessonTypesTab canAdmin={canAdmin} search={search} />}
      {tab === 'grading-scales' && <GradingScalesTab canAdmin={canAdmin} search={search} />}
      {tab === 'closures' && <StoreClosuresTab canAdmin={canAdmin} />}
    </div>
  )
}

// ─── Instructors Tab ──────────────────────────────────────────────────────────

const instructorColumns: Column<Instructor>[] = [
  { key: 'display_name', header: 'Name', sortable: true, render: (i) => <span className="font-medium">{i.displayName}</span> },
  { key: 'instruments', header: 'Instruments', render: (i) => <>{i.instruments?.join(', ') || <span className="text-muted-foreground">—</span>}</> },
  {
    key: 'is_active', header: 'Status', sortable: true,
    render: (i) => <Badge variant={i.isActive ? 'default' : 'secondary'}>{i.isActive ? 'Active' : 'Inactive'}</Badge>,
  },
]

function InstructorsTab({ canAdmin, search: _search }: { canAdmin: boolean; search: Record<string, unknown> }) {
  const navigate = useNavigate()
  const queryClient = useQueryClient()
  const { params, setPage, setSearch, setSort } = usePagination()
  const [searchInput, setSearchInput] = useState(params.q ?? '')
  const [createOpen, setCreateOpen] = useState(false)

  const { data, isLoading } = useQuery(instructorListOptions(params))

  const createMutation = useMutation({
    mutationFn: instructorMutations.create,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: instructorKeys.all })
      toast.success('Instructor created')
      setCreateOpen(false)
    },
    onError: (err) => toast.error(err.message),
  })

  function handleSearchSubmit(e: React.FormEvent) {
    e.preventDefault()
    setSearch(searchInput)
  }

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <form onSubmit={handleSearchSubmit} className="flex gap-2 max-w-sm">
          <div className="relative flex-1">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder="Search instructors..."
              value={searchInput}
              onChange={(e) => setSearchInput(e.target.value)}
              className="pl-9"
            />
          </div>
          <Button type="submit" variant="secondary">Search</Button>
        </form>
        {canAdmin && (
          <Dialog open={createOpen} onOpenChange={setCreateOpen}>
            <DialogTrigger asChild>
              <Button><Plus className="mr-2 h-4 w-4" />New Instructor</Button>
            </DialogTrigger>
            <DialogContent>
              <DialogHeader><DialogTitle>Create Instructor</DialogTitle></DialogHeader>
              <InstructorForm onSubmit={createMutation.mutate} loading={createMutation.isPending} />
            </DialogContent>
          </Dialog>
        )}
      </div>
      <DataTable
        columns={instructorColumns}
        data={data?.data ?? []}
        loading={isLoading}
        page={params.page}
        totalPages={data?.pagination.totalPages ?? 1}
        total={data?.pagination.total ?? 0}
        sort={params.sort}
        order={params.order}
        onPageChange={setPage}
        onSort={setSort}
        onRowClick={(i) => navigate({ to: '/lessons/schedule/instructors/$instructorId', params: { instructorId: i.id }, search: { tab: 'overview' } })}
      />
    </div>
  )
}

// ─── Lesson Types Tab ─────────────────────────────────────────────────────────

const lessonTypeColumns: Column<LessonType>[] = [
  { key: 'name', header: 'Name', sortable: true, render: (lt) => <span className="font-medium">{lt.name}</span> },
  { key: 'instrument', header: 'Instrument', render: (lt) => <>{lt.instrument ?? <span className="text-muted-foreground">—</span>}</> },
  { key: 'duration_minutes', header: 'Duration', sortable: true, render: (lt) => <>{lt.durationMinutes} min</> },
  { key: 'lesson_format', header: 'Format', render: (lt) => <Badge variant="outline">{lt.lessonFormat}</Badge> },
  { key: 'rate_monthly', header: 'Monthly Rate', render: (lt) => <>{lt.rateMonthly ? `$${lt.rateMonthly}` : <span className="text-muted-foreground">—</span>}</> },
  { key: 'is_active', header: 'Status', render: (lt) => <Badge variant={lt.isActive ? 'default' : 'secondary'}>{lt.isActive ? 'Active' : 'Inactive'}</Badge> },
]

function LessonTypesTab({ canAdmin, search: _search }: { canAdmin: boolean; search: Record<string, unknown> }) {
  const queryClient = useQueryClient()
  const { params, setPage, setSearch, setSort } = usePagination()
  const [searchInput, setSearchInput] = useState(params.q ?? '')
  const [createOpen, setCreateOpen] = useState(false)
  const [editTarget, setEditTarget] = useState<LessonType | null>(null)

  const { data, isLoading } = useQuery(lessonTypeListOptions(params))

  const createMutation = useMutation({
    mutationFn: lessonTypeMutations.create,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: lessonTypeKeys.all })
      toast.success('Lesson type created')
      setCreateOpen(false)
    },
    onError: (err) => toast.error(err.message),
  })

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: string; data: Record<string, unknown> }) => lessonTypeMutations.update(id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: lessonTypeKeys.all })
      toast.success('Lesson type updated')
      setEditTarget(null)
    },
    onError: (err) => toast.error(err.message),
  })

  const deleteMutation = useMutation({
    mutationFn: lessonTypeMutations.delete,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: lessonTypeKeys.all })
      toast.success('Lesson type removed')
    },
    onError: (err) => toast.error(err.message),
  })

  function handleSearchSubmit(e: React.FormEvent) {
    e.preventDefault()
    setSearch(searchInput)
  }

  const columnsWithActions: Column<LessonType>[] = [
    ...lessonTypeColumns,
    ...(canAdmin ? [{
      key: 'actions',
      header: '',
      render: (lt: LessonType) => (
        <div className="flex gap-1 justify-end">
          <Button variant="ghost" size="sm" onClick={(e) => { e.stopPropagation(); setEditTarget(lt) }}>Edit</Button>
          <Button variant="ghost" size="sm" onClick={(e) => { e.stopPropagation(); deleteMutation.mutate(lt.id) }}>
            <Trash2 className="h-4 w-4 text-destructive" />
          </Button>
        </div>
      ),
    }] : []),
  ]

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <form onSubmit={handleSearchSubmit} className="flex gap-2 max-w-sm">
          <div className="relative flex-1">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder="Search lesson types..."
              value={searchInput}
              onChange={(e) => setSearchInput(e.target.value)}
              className="pl-9"
            />
          </div>
          <Button type="submit" variant="secondary">Search</Button>
        </form>
        {canAdmin && (
          <Dialog open={createOpen} onOpenChange={setCreateOpen}>
            <DialogTrigger asChild>
              <Button><Plus className="mr-2 h-4 w-4" />New Lesson Type</Button>
            </DialogTrigger>
            <DialogContent>
              <DialogHeader><DialogTitle>Create Lesson Type</DialogTitle></DialogHeader>
              <LessonTypeForm onSubmit={createMutation.mutate} loading={createMutation.isPending} />
            </DialogContent>
          </Dialog>
        )}
      </div>

      {editTarget && (
        <Dialog open={!!editTarget} onOpenChange={(o) => { if (!o) setEditTarget(null) }}>
          <DialogContent>
            <DialogHeader><DialogTitle>Edit Lesson Type</DialogTitle></DialogHeader>
            <LessonTypeForm
              defaultValues={editTarget}
              onSubmit={(data) => updateMutation.mutate({ id: editTarget.id, data })}
              loading={updateMutation.isPending}
            />
          </DialogContent>
        </Dialog>
      )}

      <DataTable
        columns={columnsWithActions}
        data={data?.data ?? []}
        loading={isLoading}
        page={params.page}
        totalPages={data?.pagination.totalPages ?? 1}
        total={data?.pagination.total ?? 0}
        sort={params.sort}
        order={params.order}
        onPageChange={setPage}
        onSort={setSort}
      />
    </div>
  )
}

// ─── Grading Scales Tab ───────────────────────────────────────────────────────

const gradingScaleColumns: Column<GradingScale>[] = [
  { key: 'name', header: 'Name', sortable: true, render: (gs) => <span className="font-medium">{gs.name}</span> },
  {
    key: 'is_default', header: '', render: (gs) => gs.isDefault
      ? <Badge variant="default">Default</Badge>
      : null,
  },
  { key: 'levels', header: 'Levels', render: (gs) => <>{gs.levels?.length ?? 0}</> },
  { key: 'is_active', header: 'Status', render: (gs) => <Badge variant={gs.isActive ? 'default' : 'secondary'}>{gs.isActive ? 'Active' : 'Inactive'}</Badge> },
]

function GradingScalesTab({ canAdmin, search: _search }: { canAdmin: boolean; search: Record<string, unknown> }) {
  const queryClient = useQueryClient()
  const { params, setPage, setSort } = usePagination()
  const [createOpen, setCreateOpen] = useState(false)

  const { data, isLoading } = useQuery(gradingScaleListOptions(params))

  const createMutation = useMutation({
    mutationFn: gradingScaleMutations.create,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: gradingScaleKeys.all })
      toast.success('Grading scale created')
      setCreateOpen(false)
    },
    onError: (err) => toast.error(err.message),
  })

  const deleteMutation = useMutation({
    mutationFn: gradingScaleMutations.delete,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: gradingScaleKeys.all })
      toast.success('Grading scale removed')
    },
    onError: (err) => toast.error(err.message),
  })

  const columnsWithActions: Column<GradingScale>[] = [
    ...gradingScaleColumns,
    ...(canAdmin ? [{
      key: 'actions',
      header: '',
      render: (gs: GradingScale) => (
        <Button variant="ghost" size="sm" onClick={(e) => { e.stopPropagation(); deleteMutation.mutate(gs.id) }}>
          <Trash2 className="h-4 w-4 text-destructive" />
        </Button>
      ),
    }] : []),
  ]

  return (
    <div className="space-y-4">
      <div className="flex justify-end">
        {canAdmin && (
          <Dialog open={createOpen} onOpenChange={setCreateOpen}>
            <DialogTrigger asChild>
              <Button><Plus className="mr-2 h-4 w-4" />New Grading Scale</Button>
            </DialogTrigger>
            <DialogContent className="max-w-lg">
              <DialogHeader><DialogTitle>Create Grading Scale</DialogTitle></DialogHeader>
              <GradingScaleForm onSubmit={createMutation.mutate} loading={createMutation.isPending} />
            </DialogContent>
          </Dialog>
        )}
      </div>
      <DataTable
        columns={columnsWithActions}
        data={data?.data ?? []}
        loading={isLoading}
        page={params.page}
        totalPages={data?.pagination.totalPages ?? 1}
        total={data?.pagination.total ?? 0}
        sort={params.sort}
        order={params.order}
        onPageChange={setPage}
        onSort={setSort}
      />
    </div>
  )
}

// ─── Store Closures Tab ───────────────────────────────────────────────────────

function StoreClosuresTab({ canAdmin }: { canAdmin: boolean }) {
  const queryClient = useQueryClient()
  const [createOpen, setCreateOpen] = useState(false)

  const { data, isLoading } = useQuery(storeClosureListOptions())

  const createMutation = useMutation({
    mutationFn: storeClosureMutations.create,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: storeClosureKeys.all })
      toast.success('Store closure added')
      setCreateOpen(false)
    },
    onError: (err) => toast.error(err.message),
  })

  const deleteMutation = useMutation({
    mutationFn: storeClosureMutations.delete,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: storeClosureKeys.all })
      toast.success('Closure removed')
    },
    onError: (err) => toast.error(err.message),
  })

  const closures: StoreClosure[] = data ?? []

  return (
    <div className="space-y-4">
      <div className="flex justify-end">
        {canAdmin && (
          <Dialog open={createOpen} onOpenChange={setCreateOpen}>
            <DialogTrigger asChild>
              <Button><Plus className="mr-2 h-4 w-4" />Add Closure</Button>
            </DialogTrigger>
            <DialogContent>
              <DialogHeader><DialogTitle>Add Store Closure</DialogTitle></DialogHeader>
              <StoreClosureForm onSubmit={createMutation.mutate} loading={createMutation.isPending} />
            </DialogContent>
          </Dialog>
        )}
      </div>

      {isLoading ? (
        <div className="text-sm text-muted-foreground">Loading...</div>
      ) : closures.length === 0 ? (
        <div className="text-sm text-muted-foreground text-center py-8 border rounded-md">
          No store closures configured.
        </div>
      ) : (
        <div className="divide-y border rounded-md">
          {closures.map((c) => (
            <div key={c.id} className="flex items-center justify-between px-4 py-3">
              <div>
                <div className="font-medium text-sm">{c.name}</div>
                <div className="text-xs text-muted-foreground">
                  {new Date(c.startDate + 'T00:00:00').toLocaleDateString()} –{' '}
                  {new Date(c.endDate + 'T00:00:00').toLocaleDateString()}
                </div>
              </div>
              {canAdmin && (
                <Button variant="ghost" size="sm" onClick={() => deleteMutation.mutate(c.id)}>
                  <Trash2 className="h-4 w-4 text-destructive" />
                </Button>
              )}
            </div>
          ))}
        </div>
      )}
    </div>
  )
}
