import { FileInput, Stack, TextInput } from "@mantine/core";
import { useForm, UseFormInput } from "@mantine/form";
import { LinkIcon } from "@phosphor-icons/react";
import SlidePanel from "@/components/sheet/slide-panel";
import { isNotEmpty } from "@mantine/form";
import useCreateTeam from "../../hooks/use-create-team";
import useUpdateTeam from "../../hooks/use-update-team";
import toast from "@/lib/sonner";
import { logger } from "../..";
import { useQueryClient } from "@tanstack/react-query";
import { tournamentKeys } from "@/features/tournaments/queries";
import { useCallback } from "react";
import { TeamInput } from "../../types";
import { teamKeys } from "../../queries";
import SongPicker from "./song-picker";
import PlayersPicker from "./players-picker";
import imageCompression from "browser-image-compression";

interface TeamFormProps {
  close: () => void;
  initialValues?: Partial<TeamInput>;
  teamId?: string;
  tournamentId?: string;
  onSubmit?: (teamId: string) => void;
}

const TeamForm = ({
  close,
  initialValues,
  teamId,
  tournamentId,
  onSubmit
}: TeamFormProps) => {
  const isEditMode = !!teamId;

  const config: UseFormInput<TeamInput> = {
    initialValues: {
      name: initialValues?.name || "",
      // primary_color: initialValues?.primary_color,
      // accent_color: initialValues?.accent_color,
      song_id: initialValues?.song_id,
      song_name: initialValues?.song_name,
      song_artist: initialValues?.song_artist,
      song_album: initialValues?.song_album,
      song_start: initialValues?.song_start,
      song_end: initialValues?.song_end,
      song_image_url: initialValues?.song_image_url,
      logo: undefined,
      players: initialValues?.players || [],
    },
    onSubmitPreventDefault: "always",
    validate: {
      name: isNotEmpty("Name is required"),
      players: (value: string[]) =>
        value.length > 1 && value[1] !== ""
          ? undefined
          : "Players are required",
      song_name: isNotEmpty("Song is required"),
      song_start: (value, values) => {
        if (values.song_name && values.song_id) {
          if (value === undefined || value === null) {
            return "Song start time is required";
          }
        }
        return undefined;
      },
      song_end: (value, values) => {
        if (values.song_name && values.song_id) {
          if (value === undefined || value === null) {
            return "Song end time is required";
          }
          if (values.song_start !== undefined && value !== undefined) {
            const duration = value - values.song_start;
            if (duration < 10) {
              return "Song segment must be at least 10 seconds";
            }
            if (duration > 15) {
              return "Song segment must be no more than 15 seconds";
            }
          }
        }
        return undefined;
      },
    },
  };

  const form = useForm(config);
  const queryClient = useQueryClient();

  const { mutate: createTeam, isPending: createPending } =
    useCreateTeam();
  const { mutate: updateTeam, isPending: updatePending } = useUpdateTeam(
    teamId!
  );

  const isPending = createPending || updatePending;

  const handleSubmit = useCallback(
    async (values: TeamInput) => {
      const { logo, ...teamData } = values;

      const mutation = isEditMode ? updateTeam : createTeam;
      const errorMessage = isEditMode
        ? "Failed to update team"
        : "Failed to create team";

      mutation(teamData, {
        onSuccess: async (team: any) => {
          queryClient.invalidateQueries({ queryKey: teamKeys.list });
          queryClient.invalidateQueries({
            queryKey: teamKeys.details(team.id),
          });

          if (logo && team) {
            try {
              let processedLogo = logo;

              if (logo.size > 500 * 1024) {
                const compressionOptions = {
                  maxSizeMB: 0.5,
                  maxWidthOrHeight: 800,
                  useWebWorker: true,
                  fileType: logo.type,
                };

                try {
                  processedLogo = await imageCompression(logo, compressionOptions);
                  logger.info("image compressed", {
                    originalSize: logo.size,
                    compressedSize: processedLogo.size,
                    reduction: ((logo.size - processedLogo.size) / logo.size * 100).toFixed(1) + "%"
                  });
                } catch (compressionError) {
                  logger.warn("compression failed, falling back", compressionError);
                  processedLogo = logo;
                }
              }

              const formData = new FormData();
              formData.append("teamId", team.id);
              formData.append("logo", processedLogo);

              const response = await fetch("/api/teams/upload-logo", {
                method: "POST",
                body: formData,
              });

              if (!response.ok) {
                const error = await response.json();
                throw new Error(error.error || "Failed to upload logo");
              }

              const result = await response.json();


              queryClient.setQueryData(
                tournamentKeys.details(result.team!.id),
                result.team
              );
            } catch (error: any) {
              const logoErrorMessage = isEditMode
                ? `Team updated but logo upload failed: ${error.message}`
                : `Team created but logo upload failed: ${error.message}`;
              toast.error(logoErrorMessage);
              logger.error("Team logo upload error", error);
            }
          }

          if (team && team.id) {
            onSubmit?.(team.id)
          }
          close();
        },
        onError: (error: any) => {
          toast.error(`${errorMessage}: ${error.message}`);
          logger.error(`Team ${isEditMode ? "update" : "create"} error`, error);
        },
      });
    },
    [isEditMode, createTeam, updateTeam, queryClient]
  );

  return (
    <SlidePanel
      onSubmit={form.onSubmit(handleSubmit)}
      onCancel={close}
      submitText={isEditMode ? "Update Team" : "Create Team"}
      cancelText="Cancel"
      loading={isPending}
    >
      <Stack>
        <TextInput
          label="Name"
          withAsterisk
          disabled={isEditMode}
          key={form.key("name")}
          {...form.getInputProps("name")}
        />

        <FileInput
          key={form.key("logo")}
          accept="image/png,image/jpeg,image/gif,image/jpg"
          label={isEditMode ? "Change Logo" : "Logo"}
          leftSection={<LinkIcon size={16} />}
          {...form.getInputProps("logo")}
        />

        {tournamentId && (
          <PlayersPicker
            tournamentId={tournamentId}
            key={form.key("players")}
            {...form.getInputProps("players")}
            disabled={isEditMode}
          />
        )}

        <SongPicker
          form={form}
          error={form.errors.song_name as string}
        />

        {/*
          <SlidePanelField
            key={form.key("primary_color")}
            {...form.getInputProps("primary_color")}
            Component={TeamColorPicker}
            title="Select Primary Color"
            placeholder="Select Primary Color"
            label="Primary Color"
            formatValue={(value) => (
              <Group>
                <Badge variant="filled" radius="sm" color={value} />
                {value}
              </Group>
            )}
          />

          <SlidePanelField
            key={form.key("accent_color")}
            {...form.getInputProps("accent_color")}
            Component={TeamColorPicker}
            title="Select Accent Color"
            placeholder="Select Accent Color"
            label="Accent Color"
            formatValue={(value) => (
              <Group>
                <Badge variant="filled" radius="sm" color={value} />
                {value}
              </Group>
            )}
          />
        */}

      </Stack>
    </SlidePanel>
  );
};

export default TeamForm;
