"use client";

import { useState } from "react";
import { toast } from "sonner";
import {
  useChannels,
  useCreateChannel,
  useUpdateChannel,
  useDeleteChannel,
  useGenerateSchedule,
} from "@/hooks/use-channels";
import { useAuthContext } from "@/context/auth-context";
import { useConfig } from "@/hooks/use-config";
import { useRescanLibrary } from "@/hooks/use-library";
import { useChannelOrder } from "@/hooks/use-channel-order";
import { useImportChannel } from "@/hooks/use-import-channel";
import { useRegenerateAllSchedules } from "@/hooks/use-regenerate-all";
import { exportChannel } from "@/lib/channel-export";
import { DashboardHeader } from "./components/dashboard-header";
import { ChannelCard } from "./components/channel-card";
import { CreateChannelDialog } from "./components/create-channel-dialog";
import { DeleteChannelDialog } from "./components/delete-channel-dialog";
import { EditChannelSheet } from "./components/edit-channel-sheet";
import { ScheduleSheet } from "./components/schedule-sheet";
import {
  ImportChannelDialog,
  type ChannelImportData,
} from "./components/import-channel-dialog";
import { IptvExportDialog } from "./components/iptv-export-dialog";
import { TranscodeSettingsDialog } from "./components/transcode-settings-dialog";
import { ScheduleHistoryDialog } from "./components/schedule-history-dialog";
import type {
  ChannelResponse,
  ProgrammingBlock,
  RecyclePolicy,
  Weekday,
} from "@/lib/types";

export default function DashboardPage() {
  const { token } = useAuthContext();
  const { data: channels, isLoading, error } = useChannels();
  const { data: config } = useConfig();
  const capabilities = config?.provider_capabilities;

  const createChannel = useCreateChannel();
  const updateChannel = useUpdateChannel();
  const deleteChannel = useDeleteChannel();
  const generateSchedule = useGenerateSchedule();
  const rescanLibrary = useRescanLibrary();

  const { sortedChannels, handleMoveUp, handleMoveDown } = useChannelOrder(channels);
  const { isRegeneratingAll, handleRegenerateAll } = useRegenerateAllSchedules(channels, token);
  const importChannel = useImportChannel(token);

  // Dialog state
  const [iptvOpen, setIptvOpen] = useState(false);
  const [transcodeOpen, setTranscodeOpen] = useState(false);
  const [createOpen, setCreateOpen] = useState(false);
  const [importOpen, setImportOpen] = useState(false);
  const [editChannel, setEditChannel] = useState<ChannelResponse | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<ChannelResponse | null>(null);
  const [scheduleChannel, setScheduleChannel] = useState<ChannelResponse | null>(null);
  const [scheduleHistoryChannelId, setScheduleHistoryChannelId] = useState<string | null>(null);

  const handleCreate = (data: {
    name: string;
    timezone: string;
    description: string;
    access_mode?: import("@/lib/types").AccessMode;
    access_password?: string;
  }) => {
    createChannel.mutate(
      {
        name: data.name,
        timezone: data.timezone,
        description: data.description || undefined,
        access_mode: data.access_mode,
        access_password: data.access_password,
      },
      { onSuccess: () => setCreateOpen(false) },
    );
  };

  const handleEdit = (
    id: string,
    data: {
      name: string;
      description: string;
      timezone: string;
      schedule_config: { day_blocks: Record<Weekday, ProgrammingBlock[]> };
      recycle_policy: RecyclePolicy;
      auto_schedule: boolean;
      access_mode?: import("@/lib/types").AccessMode;
      access_password?: string;
      logo?: string | null;
      logo_position?: import("@/lib/types").LogoPosition;
      logo_opacity?: number;
      webhook_url?: string | null;
      webhook_poll_interval_secs?: number;
      webhook_body_template?: string | null;
      webhook_headers?: string | null;
    },
  ) => {
    updateChannel.mutate(
      { id, data },
      { onSuccess: () => setEditChannel(null) },
    );
  };

  const handleImport = async (data: ChannelImportData) => {
    const ok = await importChannel.handleImport(data);
    if (ok) setImportOpen(false);
  };

  const handleDelete = () => {
    if (!deleteTarget) return;
    deleteChannel.mutate(deleteTarget.id, {
      onSuccess: () => setDeleteTarget(null),
    });
  };

  const canTranscode = !!config?.providers?.some((p) => p.capabilities.transcode);
  const canRescan = !!capabilities?.rescan;

  return (
    <div className="mx-auto w-full max-w-5xl space-y-6 px-6 py-8">
      <DashboardHeader
        hasChannels={!!channels && channels.length > 0}
        canTranscode={canTranscode}
        canRescan={canRescan}
        isRegeneratingAll={isRegeneratingAll}
        isRescanPending={rescanLibrary.isPending}
        capabilities={capabilities}
        onTranscodeOpen={() => setTranscodeOpen(true)}
        onRescan={() =>
          rescanLibrary.mutate(undefined, {
            onSuccess: (d) =>
              toast.success(`Rescan complete: ${d.items_found} files found`),
            onError: () => toast.error("Rescan failed"),
          })
        }
        onRegenerateAll={handleRegenerateAll}
        onIptvOpen={() => setIptvOpen(true)}
        onImportOpen={() => setImportOpen(true)}
        onCreateOpen={() => setCreateOpen(true)}
      />

      {isLoading && (
        <div className="flex items-center justify-center py-20">
          <div className="h-5 w-5 animate-spin rounded-full border-2 border-zinc-700 border-t-zinc-300" />
        </div>
      )}

      {error && (
        <div className="rounded-lg border border-red-900/50 bg-red-950/20 px-4 py-3 text-sm text-red-400">
          {error.message}
        </div>
      )}

      {!isLoading && channels && channels.length === 0 && (
        <div className="flex flex-col items-center justify-center gap-3 rounded-xl border border-dashed border-zinc-800 py-20 text-center">
          <p className="text-sm text-zinc-500">No channels yet</p>
          <button
            onClick={() => setCreateOpen(true)}
            className="inline-flex items-center gap-1.5 rounded-md border border-zinc-700 bg-zinc-800 px-3 py-1.5 text-sm text-zinc-300 transition-colors hover:bg-zinc-700 hover:text-zinc-100"
          >
            Create your first channel
          </button>
        </div>
      )}

      {sortedChannels.length > 0 && (
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {sortedChannels.map((channel, idx) => (
            <ChannelCard
              key={channel.id}
              channel={channel}
              isGenerating={
                generateSchedule.isPending &&
                generateSchedule.variables === channel.id
              }
              isFirst={idx === 0}
              isLast={idx === sortedChannels.length - 1}
              onEdit={() => setEditChannel(channel)}
              onDelete={() => setDeleteTarget(channel)}
              onGenerateSchedule={() => generateSchedule.mutate(channel.id)}
              onViewSchedule={() => setScheduleChannel(channel)}
              onExport={() => exportChannel(channel)}
              onMoveUp={() => handleMoveUp(channel.id)}
              onMoveDown={() => handleMoveDown(channel.id)}
              onScheduleHistory={() => setScheduleHistoryChannelId(channel.id)}
            />
          ))}
        </div>
      )}

      {/* Dialogs / sheets */}
      <TranscodeSettingsDialog
        open={transcodeOpen}
        onOpenChange={setTranscodeOpen}
      />

      {token && (
        <IptvExportDialog
          open={iptvOpen}
          onOpenChange={setIptvOpen}
          token={token}
        />
      )}

      <ImportChannelDialog
        open={importOpen}
        onOpenChange={(open) => {
          if (!open) {
            setImportOpen(false);
            importChannel.clearError();
          }
        }}
        onSubmit={handleImport}
        isPending={importChannel.isPending}
        error={importChannel.error}
      />

      <CreateChannelDialog
        open={createOpen}
        onOpenChange={setCreateOpen}
        onSubmit={handleCreate}
        isPending={createChannel.isPending}
        error={createChannel.error?.message}
      />

      <EditChannelSheet
        channel={editChannel}
        open={!!editChannel}
        onOpenChange={(open) => {
          if (!open) setEditChannel(null);
        }}
        onSubmit={handleEdit}
        isPending={updateChannel.isPending}
        error={updateChannel.error?.message}
        providers={config?.providers ?? []}
      />

      <ScheduleSheet
        channel={scheduleChannel}
        open={!!scheduleChannel}
        onOpenChange={(open) => {
          if (!open) setScheduleChannel(null);
        }}
      />

      {scheduleHistoryChannelId && (
        <ScheduleHistoryDialog
          channelId={scheduleHistoryChannelId}
          open={!!scheduleHistoryChannelId}
          onOpenChange={open => !open && setScheduleHistoryChannelId(null)}
        />
      )}

      {deleteTarget && (
        <DeleteChannelDialog
          channelName={deleteTarget.name}
          open={!!deleteTarget}
          onOpenChange={(open) => {
            if (!open) setDeleteTarget(null);
          }}
          onConfirm={handleDelete}
          isPending={deleteChannel.isPending}
        />
      )}
    </div>
  );
}
