import React, { useCallback, useEffect, useRef, useState } from "react";

import { Alert, Box, Button, CircularProgress, Paper, Stack, Typography } from "@mui/material";

import { api, getApiErrorMessage } from "../api";
import { useAccountPlan } from "../accountPlan";
import { useI18n } from "../i18n/I18nProvider";
import { statusLabel } from "../pipeline";
import type { FocusPlanResponse, StatusSuggestion, StrategySnapshotOperationResponse, UserOperation } from "../types";
import { useToast } from "../toast";
import { DraftCard, ListCard, TwoColumnSection } from "./JobDetailsPanels";

const terminal = (status: UserOperation["status"]) => ["succeeded", "failed", "cancelled"].includes(status);

export function ApplicationStatusSuggestion({ jobId, onApplied }: { jobId: number; onApplied: () => void }) {
  const [suggestion, setSuggestion] = useState<StatusSuggestion | null>(null);
  const [busy, setBusy] = useState(false);
  const { toast } = useToast();
  const { t } = useI18n();

  useEffect(() => {
    let active = true;
    api.get<StatusSuggestion>(`/jobapplications/${jobId}/status-suggestion`)
      .then(({ data }) => { if (active) setSuggestion(data.hasSuggestion ? data : null); })
      .catch(() => { if (active) setSuggestion(null); });
    return () => { active = false; };
  }, [jobId]);

  if (!suggestion?.suggestedStatus) return null;

  const apply = async () => {
    setBusy(true);
    try {
      await api.patch(`/jobapplications/${jobId}/status`, { status: suggestion.suggestedStatus });
      setSuggestion(null);
      onApplied();
      toast(t("workspaceStatusSuggestionApplied"), "success");
    } catch (error) {
      toast(getApiErrorMessage(error, t("workspaceStatusSuggestionFailed")), "error");
    } finally {
      setBusy(false);
    }
  };

  return (
    <Alert
      severity="info"
      action={<Button color="inherit" size="small" disabled={busy} onClick={() => void apply()}>{t("workspaceStatusSuggestionApply", { status: statusLabel(t, suggestion.suggestedStatus) })}</Button>}
    >
      {t("workspaceStatusSuggestionBody", {
        current: suggestion.currentStatus ? statusLabel(t, suggestion.currentStatus) : t("workspaceStatusSuggestionCurrent"),
        suggested: statusLabel(t, suggestion.suggestedStatus),
      })}
    </Alert>
  );
}

export function ApplicationStrategySnapshot({ jobId }: { jobId: number }) {
  const { canUseAi } = useAccountPlan();
  const { toast } = useToast();
  const { t } = useI18n();
  const [plan, setPlan] = useState<FocusPlanResponse | null>(null);
  const [operation, setOperation] = useState<UserOperation | null>(null);
  const [loading, setLoading] = useState(true);
  const announced = useRef<string | null>(null);

  const loadPlan = useCallback(async () => {
    try {
      const { data } = await api.get<FocusPlanResponse>(`/jobapplications/${jobId}/focus-plan`);
      setPlan(data);
    } catch {
      setPlan(null);
    }
  }, [jobId]);

  useEffect(() => {
    let active = true;
    setLoading(true);
    Promise.all([
      loadPlan(),
      api.get<UserOperation>(`/jobapplications/${jobId}/focus-plan/operation`)
        .then(({ data }) => { if (active) setOperation(data); })
        .catch(() => { if (active) setOperation(null); }),
    ]).finally(() => { if (active) setLoading(false); });
    return () => { active = false; };
  }, [jobId, loadPlan]);

  useEffect(() => {
    if (!operation || terminal(operation.status)) return;
    const timer = window.setTimeout(() => {
      api.get<UserOperation>(`/operations/${operation.id}`)
        .then(({ data }) => setOperation(data))
        .catch(() => undefined);
    }, 1000);
    return () => window.clearTimeout(timer);
  }, [operation]);

  useEffect(() => {
    if (!operation || !terminal(operation.status)) return;
    const key = `${operation.id}:${operation.status}`;
    if (announced.current === key) return;
    announced.current = key;
    if (operation.status === "succeeded") {
      void loadPlan();
      toast(t("workspaceStrategyCompleted"), "success");
    } else if (operation.status === "failed") toast(t("workspaceStrategyFailed"), "error");
    else toast(t("workspaceStrategyCancelled"), "info");
  }, [loadPlan, operation, t, toast]);

  const generate = async () => {
    setLoading(true);
    try {
      const { data } = await api.post<StrategySnapshotOperationResponse>(`/jobapplications/${jobId}/focus-plan/operations`, { attachmentIds: null });
      announced.current = null;
      setOperation(data.operation);
      toast(data.created ? t("workspaceStrategyQueued") : t("workspaceStrategyAlreadyQueued"), "info");
    } catch (error) {
      toast(getApiErrorMessage(error, t("workspaceStrategyQueueFailed")), "error");
    } finally {
      setLoading(false);
    }
  };

  const mutateOperation = async (action: "cancel" | "retry") => {
    if (!operation) return;
    try {
      announced.current = null;
      const { data } = await api.post<UserOperation>(`/operations/${operation.id}/${action}`);
      setOperation(data);
    } catch (error) {
      toast(getApiErrorMessage(error, action === "cancel" ? t("workspaceStrategyCancelFailed") : t("workspaceStrategyRetryFailed")), "error");
    }
  };

  const working = !!operation && !terminal(operation.status);
  return (
    <Paper sx={{ p: { xs: 2, sm: 2.5 }, borderRadius: 3 }}>
      <Stack direction="row" justifyContent="space-between" alignItems="center" gap={1} sx={{ mb: 2 }}>
        <Box>
          <Typography variant="subtitle2" sx={{ fontWeight: 800 }}>{t("workspaceStrategyTitle")}</Typography>
          <Typography variant="caption" color="text.secondary">{t("workspaceStrategySubtitle")}</Typography>
        </Box>
        <Button variant="outlined" size="small" disabled={!canUseAi || loading || working} onClick={() => void generate()}>
          {!canUseAi ? t("workspaceStrategyProRequired") : plan ? t("workspaceStrategyRegenerate") : t("workspaceStrategyGenerate")}
        </Button>
      </Stack>
      {operation && operation.status !== "succeeded" ? (
        <Alert severity={operation.status === "failed" ? "error" : operation.status === "cancelled" ? "warning" : "info"} sx={{ mb: 2 }} action={<>
          {operation.canCancel ? <Button size="small" color="inherit" onClick={() => void mutateOperation("cancel")}>{t("cancel")}</Button> : null}
          {operation.canRetry ? <Button size="small" color="inherit" onClick={() => void mutateOperation("retry")}>{t("retry")}</Button> : null}
        </>}>
          {operation.progressStage || operation.status.replaceAll("_", " ")}{operation.progressPercent != null ? ` · ${operation.progressPercent}%` : ""}
        </Alert>
      ) : null}
      {loading && !plan ? <Box sx={{ py: 4, display: "flex", justifyContent: "center" }}><CircularProgress size={28} /></Box> : plan ? (
        <Stack spacing={2}>
          <DraftCard title={t("jobDetailsFocusSummary")} content={plan.strategicSummary} />
          <TwoColumnSection leftTitle={t("jobDetailsImmediatePriorities")} leftItems={plan.immediatePriorities} rightTitle={t("jobDetailsProofPoints")} rightItems={plan.proofPointsToLeadWith} />
          <TwoColumnSection leftTitle={t("jobDetailsCvBulletIdeas")} leftItems={plan.cvBulletIdeas} rightTitle={t("jobDetailsCoverLetterAngles")} rightItems={plan.coverLetterAngles} />
          <ListCard title={t("jobDetailsFollowUpApproach")} items={plan.followUpApproach} />
        </Stack>
      ) : <Typography color="text.secondary">{t("workspaceStrategyEmpty")}</Typography>}
    </Paper>
  );
}
