import { useCallback, useState } from "react";
import { Alert, Button, Flex, Group, Paper, Stack, Text } from "@mantine/core";
import { CheckIcon, LightningIcon } from "@phosphor-icons/react";
import { Match } from "@/features/matches/types";
import { useAuth } from "@/contexts/auth-context";
import {
  useReportMatchScore,
  useConfirmMatchScore,
  useClearMatchReport,
} from "@/features/matches/queries";
import { useSheet } from "@/hooks/use-sheet";
import Sheet from "@/components/sheet/sheet";
import { MatchForm } from "./match-form";
import toast from "@/lib/sonner";
import { Trans, useLingui } from "@lingui/react/macro";

const teamId = (t: Match["home"]): string | undefined =>
  !t ? undefined : typeof t === "string" ? t : t.id;

const teamPlayerIds = (t: Match["home"]): string[] =>
  t && typeof t !== "string" ? (t.players ?? []).map((p) => p.id) : [];

const teamName = (t: Match["home"]): string | undefined =>
  t && typeof t !== "string" ? t.name : undefined;

interface MatchReportProps {
  match: Match;
  compact?: boolean;
}

export const MatchReport: React.FC<MatchReportProps> = ({ match, compact }) => {
  const { user } = useAuth();
  const formSheet = useSheet();
  const { t } = useLingui();
  const [acknowledgedReport, setAcknowledgedReport] = useState<string | null>(
    null
  );

  const homeId = teamId(match.home);
  const onHome = !!user?.id && teamPlayerIds(match.home).includes(user.id);
  const onAway = !!user?.id && teamPlayerIds(match.away).includes(user.id);
  const isParticipant = onHome || onAway;

  const hasPending =
    match.reported_by_team != null &&
    match.reported_home_cups != null &&
    match.reported_away_cups != null;

  const reportedByHome = hasPending && match.reported_by_team === homeId;
  const reportingTeam = hasPending
    ? reportedByHome
      ? match.home
      : match.away
    : undefined;
  const opposingTeam = reportedByHome ? match.away : match.home;
  const reportedByMine =
    hasPending && ((reportedByHome && onHome) || (!reportedByHome && onAway));

  const pendingSignature = hasPending
    ? [
        match.reported_by_team,
        match.reported_home_cups,
        match.reported_away_cups,
        match.reported_ot_count ?? 0,
      ].join(":")
    : null;

  const sheetTakenOver =
    formSheet.isOpen &&
    isParticipant &&
    hasPending &&
    !reportedByMine &&
    pendingSignature !== acknowledgedReport;

  const report = useReportMatchScore(user?.id, {
    onSuccess: (data: any) => {
      if (data?.finalized) {
        toast.success(t`Score confirmed 🍻`);
        if (data.downstreamReset) {
          toast.error(
            t`Downstream matches were reset because the correction changed who advances.`
          );
        }
        if (data.groupEditAfterKnockout) {
          toast.error(
            t`Group result changed after the bracket was seeded — reseed the knockout stage if needed.`
          );
        }
      }
    },
  });

  const confirm = useConfirmMatchScore({
    onSuccess: (data: any) => {
      if (data?.downstreamReset) {
        toast.error(
          t`Downstream matches were reset because the correction changed who advances.`
        );
      }
      if (data?.groupEditAfterKnockout) {
        toast.error(
          t`Group result changed after the bracket was seeded — reseed the knockout stage if needed.`
        );
      }
    },
  });

  const clear = useClearMatchReport();

  const submitReport = useCallback(
    (data: { home_cups: number; away_cups: number; ot_count: number }) => {
      report.mutate({ data: { ...data, matchId: match.id } });
      formSheet.close();
      toast.success(t`Score submitted — waiting for the other team`);
    },
    [report, match.id, formSheet.close, t]
  );

  const submitConfirm = useCallback(() => {
    confirm.mutate({ data: { matchId: match.id } });
    formSheet.close();
    toast.success(t`Score confirmed 🍻`);
  }, [confirm, match.id, formSheet.close, t]);

  const submitClear = useCallback(() => {
    clear.mutate({ data: { matchId: match.id } });
    toast.success(t`Report cleared`);
  }, [clear, match.id, t]);

  const openForm = useCallback(() => {
    setAcknowledgedReport(pendingSignature);
    formSheet.open();
  }, [pendingSignature, formSheet.open]);

  const dismissTakeover = useCallback(() => {
    setAcknowledgedReport(pendingSignature);
  }, [pendingSignature]);

  if (match.status !== "started") return null;

  const scoreText = hasPending
    ? `${match.reported_home_cups}–${match.reported_away_cups}`
    : "";
  const size = compact ? "compact-xs" : "sm";

  const formSheetEl = (
    <Sheet
      title={sheetTakenOver ? t`Confirm Score` : t`Report Score`}
      {...formSheet.props}
    >
      {sheetTakenOver ? (
        <Stack gap="md">
          <Alert
            variant="light"
            color="yellow"
            icon={<LightningIcon size={18} weight="fill" />}
            title={t`${teamName(reportingTeam) ?? t`The other team`} just reported a score`}
          >
            <Trans>Does this look right?</Trans>
          </Alert>

          <Paper withBorder p="md">
            <Group justify="center" gap="md" wrap="nowrap">
              <Stack gap={2} align="center" style={{ flex: 1, minWidth: 0 }}>
                <Text size="sm" fw={600} ta="center" lineClamp={1}>
                  {teamName(match.home) ?? t({ message: "Home", context: "match team" })}
                </Text>
                <Text fz={34} fw={700} lh={1.2}>
                  {match.reported_home_cups}
                </Text>
              </Stack>
              <Text c="dimmed" fw={600}>
                –
              </Text>
              <Stack gap={2} align="center" style={{ flex: 1, minWidth: 0 }}>
                <Text size="sm" fw={600} ta="center" lineClamp={1}>
                  {teamName(match.away) ?? t({ message: "Away", context: "match team" })}
                </Text>
                <Text fz={34} fw={700} lh={1.2}>
                  {match.reported_away_cups}
                </Text>
              </Stack>
            </Group>
          </Paper>

          <Stack gap="xs">
            <Button
              fullWidth
              leftSection={<CheckIcon size={14} weight="bold" />}
              onClick={submitConfirm}
              loading={confirm.isPending}
            >
              <Trans>Confirm {scoreText}</Trans>
            </Button>
            <Button
              fullWidth
              variant="default"
              onClick={dismissTakeover}
              disabled={confirm.isPending}
            >
              <Trans>Not right — enter our score</Trans>
            </Button>
          </Stack>
        </Stack>
      ) : (
        <MatchForm
          match={match}
          onSubmit={submitReport}
          onCancel={formSheet.close}
          loading={report.isPending}
        />
      )}
    </Sheet>
  );

  if (isParticipant && !hasPending) {
    return (
      <>
        <Button
          size={size}
          fullWidth={!compact}
          onClick={openForm}
          loading={report.isPending}
        >
          <Trans>Report Score</Trans>
        </Button>
        {formSheetEl}
      </>
    );
  }

  if (hasPending) {
    if (reportedByMine) {
      return (
        <Flex
          direction={compact ? "column" : "row"}
          align={compact ? "stretch" : "center"}
          justify="space-between"
          gap={compact ? 4 : "xs"}
        >
          <Text size="xs" c="dimmed" lineClamp={2} style={{ minWidth: 0 }}>
            <Trans>
              Waiting for {teamName(opposingTeam) ?? t`the other team`} to confirm{" "}
              ·{" "}
              <Text span fw={600} c="bright">
                {scoreText}
              </Text>
            </Trans>
          </Text>
          <Button
            size={size}
            variant="subtle"
            color="red"
            onClick={submitClear}
            loading={clear.isPending}
            style={{ flexShrink: 0 }}
          >
            <Trans>Cancel</Trans>
          </Button>
        </Flex>
      );
    }

    if (isParticipant) {
      return (
        <>
          <Stack gap={6}>
            <Text size="xs" c="dimmed" lineClamp={2}>
              <Trans>
                {teamName(reportingTeam) ?? t`Opponent`} reported{" "}
                <Text span fw={600} c="bright">
                  {scoreText}
                </Text>
              </Trans>
            </Text>
            <Group gap="xs" wrap="nowrap">
              <Button
                size={size}
                leftSection={<CheckIcon size={12} weight="bold" />}
                onClick={submitConfirm}
                loading={confirm.isPending}
                style={{ flex: 1 }}
              >
                <Trans>Confirm</Trans>
              </Button>
              <Button
                size={size}
                variant="default"
                onClick={openForm}
                disabled={confirm.isPending}
              >
                <Trans>Not right</Trans>
              </Button>
            </Group>
          </Stack>
          {formSheetEl}
        </>
      );
    }

    return (
      <Text size="xs" c="dimmed" lineClamp={2}>
        <Trans>
          Pending: {scoreText} · reported by {teamName(reportingTeam) ?? t`a team`}
        </Trans>
      </Text>
    );
  }

  return null;
};
