import { useEffect, useMemo, useState } from 'react'
import { useParams } from 'react-router-dom'
import type { CreateScheduleJobRequest, ScheduleJob } from '@opencode-manager/shared/types'
import {
  useCancelRepoScheduleRun,
  useCreateRepoSchedule,
  useDeleteRepoSchedule,
  useRepoSchedule,
  useRepoScheduleRun,
  useRepoScheduleRuns,
  useRepoSchedules,
  useRunRepoSchedule,
  useUpdateRepoSchedule,
} from '@/hooks/useSchedules'
import { useRepoActivity } from '@/hooks/useRepoActivity'
import { useWorkspace } from '@/hooks/useWorkspace'
import { ScheduleJobDialog, JobsTab, JobDetailTab, RunHistoryTab, ScheduleTabMenu } from '@/components/schedules'
import { useScheduleTab } from '@/hooks/useMobileTabBar'
import { toUpdateScheduleRequest, getJobStatusTone } from '@/components/schedules/schedule-utils'
import { Header } from '@/components/ui/header'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Card, CardContent } from '@/components/ui/card'
import { DeleteDialog } from '@/components/ui/delete-dialog'
import { cn } from '@/lib/utils'
import { CalendarClock, Loader2, Plus } from 'lucide-react'

export function Schedules() {
  const { id } = useParams<{ id: string }>()
  const repoId = id ? Number(id) : undefined
  const [selectedJobId, setSelectedJobId] = useState<number | null>(null)
  const [selectedRunId, setSelectedRunId] = useState<number | null>(null)
  const [dialogOpen, setDialogOpen] = useState(false)
  const [editingJob, setEditingJob] = useState<ScheduleJob | undefined>()
  const [deleteJobId, setDeleteJobId] = useState<number | null>(null)
  const { scheduleTab: activeTab, setScheduleTab: setActiveTab } = useScheduleTab()

  const { workspace, isLoading: workspaceLoading } = useWorkspace(repoId)

  useRepoActivity(repoId ?? 0, Boolean(workspace) && workspace?.kind === 'repo')

  const { data: jobs, isLoading: jobsLoading } = useRepoSchedules(repoId)
  const { data: selectedJob, isFetching: isJobFetching } = useRepoSchedule(repoId, selectedJobId)
  const { data: runs, isLoading: runsLoading } = useRepoScheduleRuns(repoId, selectedJobId, 30)
  const { data: selectedRunDetails, isLoading: selectedRunLoading } = useRepoScheduleRun(repoId, selectedJobId, selectedRunId)

  const createMutation = useCreateRepoSchedule()
  const updateMutation = useUpdateRepoSchedule()
  const deleteMutation = useDeleteRepoSchedule()
  const runMutation = useRunRepoSchedule()
  const cancelRunMutation = useCancelRepoScheduleRun()

  useEffect(() => {
    if (!jobs?.length) {
      setSelectedJobId(null)
      setActiveTab('jobs')
      return
    }

    const stillExists = selectedJobId !== null && jobs.some((job) => job.id === selectedJobId)
    if (!stillExists) {
      setSelectedJobId(jobs[0]?.id ?? null)
      setActiveTab('jobs')
    }
  }, [jobs, selectedJobId, setActiveTab])

  useEffect(() => {
    if (!runs?.length) {
      setSelectedRunId(null)
      return
    }

    const stillExists = selectedRunId !== null && runs.some((run) => run.id === selectedRunId)
    if (!stillExists) {
      setSelectedRunId(runs[0]?.id ?? null)
    }
  }, [runs, selectedRunId])



  const activeRunSummary = useMemo(() => runs?.find((run) => run.id === selectedRunId) ?? null, [runs, selectedRunId])
  const activeRun = selectedRunDetails ?? activeRunSummary
  const runningRun = useMemo(() => runs?.find((run) => run.status === 'running') ?? null, [runs])

  if (workspaceLoading || jobsLoading) {
    return (
      <div className="flex items-center justify-center min-h-screen bg-background">
        <Loader2 className="w-8 h-8 animate-spin text-muted-foreground" />
      </div>
    )
  }

  if (!workspace || repoId === undefined) {
    return (
      <div className="flex items-center justify-center min-h-screen bg-background">
        <p className="text-muted-foreground">
          {repoId === 0 ? 'Workspace not found' : 'Repository not found'}
        </p>
      </div>
    )
  }
  const enabledCount = jobs?.filter((job) => job.enabled).length ?? 0
  const hasJobs = (jobs?.length ?? 0) > 0

  const handleCreate = (data: CreateScheduleJobRequest) => {
    createMutation.mutate({ repoId: repoId!, data }, {
      onSuccess: (job) => {
        setSelectedJobId(job.id)
        setDialogOpen(false)
        setEditingJob(undefined)
      },
    })
  }

  const handleUpdate = (data: CreateScheduleJobRequest) => {
    if (!editingJob) {
      return
    }

    updateMutation.mutate({
      repoId: repoId!,
      jobId: editingJob.id,
      data: toUpdateScheduleRequest(data),
    }, {
      onSuccess: () => {
        setDialogOpen(false)
        setEditingJob(undefined)
      },
    })
  }

  const handleDelete = () => {
    if (deleteJobId === null) {
      return
    }

    deleteMutation.mutate({ repoId: repoId!, jobId: deleteJobId }, {
      onSuccess: () => {
        if (selectedJobId === deleteJobId) {
          setSelectedJobId(null)
        }
        setDeleteJobId(null)
      },
    })
  }

  const handleToggleEnabled = () => {
    if (!selectedJob) {
      return
    }

    updateMutation.mutate({
      repoId: repoId!,
      jobId: selectedJob.id,
      data: { enabled: !selectedJob.enabled },
    })
  }

  const handleRunNow = () => {
    if (!selectedJob) {
      return
    }

    runMutation.mutate({ repoId: repoId!, jobId: selectedJob.id }, {
      onSuccess: (run) => {
        setSelectedRunId(run.id)
      },
    })
  }

  const handleCancelRun = () => {
    if (!activeRun || activeRun.status !== 'running') {
      return
    }

    cancelRunMutation.mutate({
      repoId: repoId!,
      jobId: activeRun.jobId,
      runId: activeRun.id,
    }, {
      onSuccess: (run) => {
        setSelectedRunId(run.id)
      },
    })
  }

  const handleSelectJob = (jobId: number) => {
    setSelectedJobId(jobId)
    setActiveTab('detail')
  }

  return (
    <div className="h-dvh max-h-dvh overflow-hidden bg-background flex flex-col pb-[calc(env(safe-area-inset-bottom)+56px)] sm:pb-0">
      <Header>
        <Header.BackButton to={workspace.backHref} />
        <div className="min-w-0 flex-1 px-3">
          <Header.Title className="truncate">{workspace.name}</Header.Title>
          <p className="text-xs text-muted-foreground truncate">{workspace.subtitle}</p>
        </div>
        <div className="flex items-center gap-2">
          <Badge variant="outline" className="h-6 rounded-full px-2 text-xs">{jobs?.length ?? 0} jobs</Badge>
          <Badge variant="outline" className={cn('h-6 rounded-full px-2 text-xs', getJobStatusTone({ enabled: true } as ScheduleJob))}>{enabledCount} enabled</Badge>
          <Header.Actions>
            <Button onClick={() => { setEditingJob(undefined); setDialogOpen(true) }} size="sm" className="hidden sm:flex">
              <Plus className="w-4 h-4 mr-2" />
              New Schedule
            </Button>
            <Button onClick={() => { setEditingJob(undefined); setDialogOpen(true) }} size="sm" className="sm:hidden h-10 w-10 p-0">
              <Plus className="w-5 h-5" />
            </Button>
          </Header.Actions>
        </div>
      </Header>

      <div className="flex flex-1 min-h-0 flex-col overflow-hidden px-2 md:px-6">
        {!hasJobs ? (
          <div className="flex min-h-0 flex-1 h-full items-start">
            <Card className="max-w-3xl border-dashed border-border/70">
              <CardContent className="flex flex-col items-start gap-4 p-8 sm:p-10">
                <div className="rounded-full border border-border bg-muted/40 p-3">
                  <CalendarClock className="h-6 w-6 text-muted-foreground" />
                </div>
                <div className="space-y-2">
                  <p className="text-xl font-semibold tracking-tight">No schedules yet</p>
                  <p className="text-sm text-muted-foreground">Create a schedule for this repo to automate recurring agent work, then inspect runs, logs, and sessions here.</p>
                </div>
                <Button onClick={() => { setEditingJob(undefined); setDialogOpen(true) }}>
                  <Plus className="w-4 h-4 mr-2" />
                  Create First Schedule
                </Button>
              </CardContent>
            </Card>
          </div>
        ) : (
          <>
            {activeTab === 'jobs' && (
              <JobsTab
                jobs={jobs ?? []}
                selectedJobId={selectedJobId}
                onSelectJob={handleSelectJob}
              />
            )}
            {activeTab === 'detail' && (
              <JobDetailTab
                selectedJob={selectedJob}
                onEdit={(job) => { setEditingJob(job); setDialogOpen(true) }}
                onDelete={setDeleteJobId}
                onToggleEnabled={handleToggleEnabled}
                onRunNow={handleRunNow}
                updatePending={updateMutation.isPending}
                runPending={runMutation.isPending}
                runningRun={Boolean(runningRun)}
                isJobFetching={isJobFetching}
              />
            )}
            {activeTab === 'runs' && (
              <RunHistoryTab
                repoId={repoId}
                selectedJob={selectedJob}
                runs={runs}
                runsLoading={runsLoading}
                onSelectRun={setSelectedRunId}
                activeRun={activeRun}
                selectedRunLoading={selectedRunLoading}
                onCancelRun={handleCancelRun}
                cancelRunPending={cancelRunMutation.isPending}
              />
            )}
          </>
        )}
      </div>

      {hasJobs && (
        <div className="sm:block hidden">
          <ScheduleTabMenu
            activeTab={activeTab}
            onTabChange={(tab) => setActiveTab(tab)}
          />
        </div>
      )}

      <ScheduleJobDialog
        open={dialogOpen}
        onOpenChange={(open) => {
          setDialogOpen(open)
          if (!open) {
            setEditingJob(undefined)
          }
        }}
        job={editingJob}
        isSaving={createMutation.isPending || updateMutation.isPending}
        onSubmit={editingJob ? handleUpdate : handleCreate}
      />

      <DeleteDialog
        open={deleteJobId !== null}
        onOpenChange={(open) => !open && setDeleteJobId(null)}
        onConfirm={handleDelete}
        onCancel={() => setDeleteJobId(null)}
        title="Delete Schedule"
        description="This removes the job definition and all recorded run history for it."
        isDeleting={deleteMutation.isPending}
      />
    </div>
  )
}
