import { BORDER_RADIUS, COLORS, SPACING } from "@/constants/theme";
import { useAuth } from "@/contexts/AuthContext";
import {
  CompanyDB,
  marcarCorridaComoSincronizada,
  obterCorridas,
  obterEmpresas,
  upsertEmpresaLocal,
} from "@/services/db";
import { api } from "@/server/api";
import { router } from "expo-router";
import React, { useState } from "react";
import {
  ActivityIndicator,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";

type SyncStatus = "pending" | "syncing" | "success" | "error";

type SyncItem = {
  key: string;
  label: string;
  description: string;
  status: SyncStatus;
  detail: string;
};

const INITIAL_ITEMS: SyncItem[] = [
  {
    key: "upload_empresas",
    label: "Empresas → Servidor",
    description: "Enviar cadastro de empresas ao servidor",
    status: "pending",
    detail: "",
  },
  {
    key: "download_empresas",
    label: "Servidor → Empresas",
    description: "Baixar empresas se cadastro estiver vazio",
    status: "pending",
    detail: "",
  },
  {
    key: "upload_corridas",
    label: "Corridas → Servidor",
    description: "Verificar e enviar corridas ausentes no servidor",
    status: "pending",
    detail: "",
  },
];

export default function SincronizarPage() {
  const { user } = useAuth();
  const [items, setItems] = useState<SyncItem[]>(INITIAL_ITEMS);
  const [syncing, setSyncing] = useState(false);
  const [done, setDone] = useState(false);

  const update = (key: string, patch: Partial<SyncItem>) =>
    setItems((prev) =>
      prev.map((i) => (i.key === key ? { ...i, ...patch } : i)),
    );

  const reset = () => {
    setItems(INITIAL_ITEMS);
    setDone(false);
  };

  const handleSync = async () => {
    if (!user?.id) return;
    setSyncing(true);
    setDone(false);
    setItems(INITIAL_ITEMS);

    // ── 1. Upload Companies (sempre) ───────────────────────────
    update("upload_empresas", { status: "syncing" });
    let localCount = 0;
    try {
      const localEmpresas = await obterEmpresas();
      localCount = localEmpresas.length;
      await api.post("/sync/companies", { companies: localEmpresas });
      update("upload_empresas", {
        status: "success",
        detail: `${localCount} empresa${localCount !== 1 ? "s" : ""} enviada${localCount !== 1 ? "s" : ""}`,
      });
    } catch (e: any) {
      update("upload_empresas", {
        status: "error",
        detail: e?.response?.data?.error ?? e?.message ?? "Falha na conexão",
      });
    }

    // ── 2. Download Companies (só se local estiver vazio) ───────
    update("download_empresas", { status: "syncing" });
    try {
      if (localCount === 0) {
        const { data: resEmpresas } = await api.get("/sync/companies");
        const rawEmpresas: CompanyDB[] = resEmpresas.data ?? [];
        for (const c of rawEmpresas) {
          await upsertEmpresaLocal({
            id: c.id,
            name: c.name,
            cost_per_km: Number(c.cost_per_km),
            notes: c.notes ?? "",
          });
        }
        update("download_empresas", {
          status: "success",
          detail: `${rawEmpresas.length} empresa${rawEmpresas.length !== 1 ? "s" : ""} baixada${rawEmpresas.length !== 1 ? "s" : ""}`,
        });
      } else {
        update("download_empresas", {
          status: "success",
          detail: "Cadastro local já possui dados",
        });
      }
    } catch (e: any) {
      update("download_empresas", {
        status: "error",
        detail: e?.response?.data?.error ?? e?.message ?? "Falha na conexão",
      });
    }

    // ── 3. Verificar e enviar corridas ausentes no servidor ────
    update("upload_corridas", { status: "syncing" });
    try {
      const todasCorridas = await obterCorridas(user.id);

      if (todasCorridas.length === 0) {
        update("upload_corridas", { status: "success", detail: "Nenhuma corrida registrada" });
      } else {
        const { data: resRides } = await api.get("/sync/rides");
        const backendIds = new Set<string>(
          (resRides.data ?? []).map((r: { id: string }) => r.id),
        );

        const ausentes = todasCorridas.filter((r) => !backendIds.has(r.id));

        if (ausentes.length === 0) {
          update("upload_corridas", { status: "success", detail: "Todas as corridas já estão no servidor" });
        } else {
          await api.post("/sync/rides", { rides: ausentes });
          for (const ride of ausentes) {
            await marcarCorridaComoSincronizada(ride.id);
          }
          update("upload_corridas", {
            status: "success",
            detail: `${ausentes.length} corrida${ausentes.length !== 1 ? "s" : ""} enviada${ausentes.length !== 1 ? "s" : ""}`,
          });
        }
      }
    } catch (e: any) {
      update("upload_corridas", {
        status: "error",
        detail: e?.response?.data?.error ?? e?.message ?? "Falha na conexão",
      });
    }

    setSyncing(false);
    setDone(true);
  };

  const allSuccess = items.every((i) => i.status === "success");
  const hasError = items.some((i) => i.status === "error");

  return (
    <SafeAreaView style={styles.container}>
      {/* Header */}
      <View style={styles.header}>
        <TouchableOpacity
          onPress={() => router.back()}
          style={styles.backButton}
          activeOpacity={0.7}
        >
          <Text style={styles.backIcon}>←</Text>
          <Text style={styles.backLabel}>Voltar</Text>
        </TouchableOpacity>
      </View>

      <ScrollView
        contentContainerStyle={styles.scrollContent}
        showsVerticalScrollIndicator={false}
      >
        <View style={styles.titleSection}>
          <Text style={styles.title}>Sincronizar</Text>
          <Text style={styles.subtitle}>
            Sincronizar dados com o servidor
          </Text>
        </View>

        {/* Status geral após conclusão */}
        {done && (
          <View
            style={[
              styles.resultBanner,
              allSuccess ? styles.resultBannerSuccess : styles.resultBannerError,
            ]}
          >
            <Text style={styles.resultBannerText}>
              {allSuccess
                ? "✓  Todos os dados sincronizados com sucesso"
                : "⚠  Sincronização concluída com erros"}
            </Text>
          </View>
        )}

        {/* Timeline */}
        <View style={styles.timeline}>
          {items.map((item, index) => {
            const isLast = index === items.length - 1;
            return (
              <View key={item.key} style={styles.timelineRow}>
                {/* Track: linha + círculo */}
                <View style={styles.track}>
                  <NodeCircle status={item.status} />
                  {!isLast && (
                    <View
                      style={[
                        styles.connector,
                        item.status === "success" && styles.connectorSuccess,
                        item.status === "error" && styles.connectorError,
                      ]}
                    />
                  )}
                </View>

                {/* Conteúdo */}
                <View style={styles.itemContent}>
                  <View style={styles.itemHeader}>
                    <Text style={styles.itemLabel}>{item.label}</Text>
                    {item.status === "success" && (
                      <Text style={styles.badgeSuccess}>✓ OK</Text>
                    )}
                    {item.status === "error" && (
                      <Text style={styles.badgeError}>✗ Erro</Text>
                    )}
                  </View>
                  <Text style={styles.itemDescription}>{item.description}</Text>
                  {item.detail !== "" && (
                    <Text
                      style={[
                        styles.itemDetail,
                        item.status === "success" && styles.itemDetailSuccess,
                        item.status === "error" && styles.itemDetailError,
                      ]}
                    >
                      {item.detail}
                    </Text>
                  )}
                </View>
              </View>
            );
          })}
        </View>

        {/* Botões */}
        <View style={styles.actions}>
          {done && hasError && (
            <TouchableOpacity
              style={styles.retryButton}
              onPress={reset}
              activeOpacity={0.8}
            >
              <Text style={styles.retryButtonText}>Redefinir</Text>
            </TouchableOpacity>
          )}

          <TouchableOpacity
            style={[
              styles.syncButton,
              syncing && styles.syncButtonDisabled,
            ]}
            onPress={handleSync}
            disabled={syncing}
            activeOpacity={0.85}
          >
            {syncing ? (
              <ActivityIndicator color={COLORS.background} size="small" />
            ) : (
              <Text style={styles.syncButtonText}>
                {done ? "Sincronizar novamente" : "Iniciar sincronização"}
              </Text>
            )}
          </TouchableOpacity>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
}

function NodeCircle({ status }: { status: SyncStatus }) {
  if (status === "syncing") {
    return (
      <View style={[styles.circle, styles.circleSyncing]}>
        <ActivityIndicator color={COLORS.warning} size="small" />
      </View>
    );
  }
  return (
    <View
      style={[
        styles.circle,
        status === "success" && styles.circleSuccess,
        status === "error" && styles.circleError,
        status === "pending" && styles.circlePending,
      ]}
    >
      {status === "success" && <Text style={styles.circleIcon}>✓</Text>}
      {status === "error" && <Text style={styles.circleIcon}>✗</Text>}
    </View>
  );
}

const CIRCLE_SIZE = 36;
const CONNECTOR_WIDTH = 2;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: COLORS.background,
  },

  // Header
  header: {
    paddingHorizontal: SPACING.lg,
    paddingVertical: SPACING.md,
    borderBottomWidth: 1,
    borderBottomColor: COLORS.border,
  },
  backButton: {
    flexDirection: "row",
    alignItems: "center",
    gap: SPACING.xs,
    alignSelf: "flex-start",
  },
  backIcon: { fontSize: 18, color: COLORS.text },
  backLabel: { fontSize: 15, color: COLORS.textSecondary, fontWeight: "500" },

  scrollContent: {
    padding: SPACING.lg,
    paddingBottom: 48,
  },

  titleSection: {
    marginBottom: SPACING.xl,
    marginTop: SPACING.md,
  },
  title: {
    fontSize: 28,
    fontWeight: "800",
    color: COLORS.text,
    marginBottom: 4,
  },
  subtitle: {
    fontSize: 14,
    color: COLORS.textTertiary,
  },

  // Banner de resultado
  resultBanner: {
    borderRadius: BORDER_RADIUS.lg,
    padding: SPACING.md,
    marginBottom: SPACING.xl,
    borderWidth: 1,
  },
  resultBannerSuccess: {
    backgroundColor: "#0d2b1f",
    borderColor: COLORS.success,
  },
  resultBannerError: {
    backgroundColor: "#2b0d0d",
    borderColor: COLORS.error,
  },
  resultBannerText: {
    fontSize: 14,
    fontWeight: "600",
    color: COLORS.text,
  },

  // Timeline
  timeline: {
    marginBottom: SPACING.xl,
  },
  timelineRow: {
    flexDirection: "row",
    alignItems: "flex-start",
  },

  // Track (círculo + conector)
  track: {
    alignItems: "center",
    width: CIRCLE_SIZE + SPACING.lg,
  },
  circle: {
    width: CIRCLE_SIZE,
    height: CIRCLE_SIZE,
    borderRadius: CIRCLE_SIZE / 2,
    justifyContent: "center",
    alignItems: "center",
    borderWidth: 2,
    zIndex: 1,
  },
  circlePending: {
    backgroundColor: COLORS.surface,
    borderColor: COLORS.border,
  },
  circleSyncing: {
    backgroundColor: COLORS.surface,
    borderColor: COLORS.warning,
  },
  circleSuccess: {
    backgroundColor: "#0d2b1f",
    borderColor: COLORS.success,
  },
  circleError: {
    backgroundColor: "#2b0d0d",
    borderColor: COLORS.error,
  },
  circleIcon: {
    fontSize: 16,
    fontWeight: "800",
    color: COLORS.text,
  },
  connector: {
    width: CONNECTOR_WIDTH,
    flex: 1,
    minHeight: 56,
    backgroundColor: COLORS.border,
    marginTop: 2,
    marginBottom: 2,
  },
  connectorSuccess: {
    backgroundColor: COLORS.success,
  },
  connectorError: {
    backgroundColor: COLORS.error,
  },

  // Item content
  itemContent: {
    flex: 1,
    paddingTop: SPACING.xs,
    paddingBottom: SPACING.xl,
    paddingLeft: SPACING.md,
  },
  itemHeader: {
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
    marginBottom: 3,
  },
  itemLabel: {
    fontSize: 16,
    fontWeight: "700",
    color: COLORS.text,
  },
  itemDescription: {
    fontSize: 12,
    color: COLORS.textTertiary,
    marginBottom: 4,
  },
  itemDetail: {
    fontSize: 12,
    fontWeight: "600",
    color: COLORS.textSecondary,
  },
  itemDetailSuccess: {
    color: COLORS.success,
  },
  itemDetailError: {
    color: COLORS.error,
  },

  // Badges
  badgeSuccess: {
    fontSize: 12,
    fontWeight: "700",
    color: COLORS.success,
    backgroundColor: "#0d2b1f",
    paddingHorizontal: SPACING.sm,
    paddingVertical: 2,
    borderRadius: BORDER_RADIUS.sm,
  },
  badgeError: {
    fontSize: 12,
    fontWeight: "700",
    color: COLORS.error,
    backgroundColor: "#2b0d0d",
    paddingHorizontal: SPACING.sm,
    paddingVertical: 2,
    borderRadius: BORDER_RADIUS.sm,
  },

  // Botões
  actions: {
    gap: SPACING.sm,
  },
  syncButton: {
    backgroundColor: COLORS.text,
    borderRadius: BORDER_RADIUS.lg,
    paddingVertical: SPACING.lg,
    alignItems: "center",
  },
  syncButtonDisabled: {
    backgroundColor: COLORS.borderLight,
  },
  syncButtonText: {
    fontSize: 15,
    fontWeight: "700",
    color: COLORS.background,
  },
  retryButton: {
    backgroundColor: COLORS.surface,
    borderRadius: BORDER_RADIUS.lg,
    paddingVertical: SPACING.md,
    alignItems: "center",
    borderWidth: 1,
    borderColor: COLORS.border,
  },
  retryButtonText: {
    fontSize: 14,
    fontWeight: "600",
    color: COLORS.textSecondary,
  },
});
