<template>
  <div class="space-y-4">
    <!-- Chart Header -->
    <div class="flex justify-between items-center">
      <div>
        <h3 class="text-lg font-semibold text-gray-900">
          Cash Flow Projection
        </h3>
        <p class="text-sm text-gray-600">
          {{ selectedWeeks }}-week runway analysis
        </p>
      </div>
      <div class="flex items-center space-x-6">
        <!-- Week Controls -->
        <div class="flex space-x-2">
          <UButton
            @click="selectedWeeks = 8"
            :variant="selectedWeeks === 8 ? 'solid' : 'outline'"
            size="sm">
            8 Weeks
          </UButton>
          <UButton
            @click="selectedWeeks = 13"
            :variant="selectedWeeks === 13 ? 'solid' : 'outline'"
            size="sm">
            13 Weeks
          </UButton>
          <UButton
            @click="selectedWeeks = 26"
            :variant="selectedWeeks === 26 ? 'solid' : 'outline'"
            size="sm">
            26 Weeks
          </UButton>
        </div>

        <!-- Balance Info -->
        <div class="flex space-x-4">
          <div class="text-center">
            <p class="text-sm text-gray-600">Starting Balance</p>
            <p class="font-semibold text-blue-600">
              {{ formatCurrency(startingBalance) }}
            </p>
          </div>
          <div class="text-center">
            <p class="text-sm text-gray-600">Projected Balance</p>
            <p class="font-semibold" :class="projectedBalanceColor">
              {{ formatCurrency(endingBalance) }}
            </p>
          </div>
        </div>
      </div>
    </div>

    <!-- Chart Container -->
    <div class="relative h-64 bg-gray-50 rounded-lg p-4">
      <!-- Y-axis labels -->
      <div
        class="absolute left-4 top-4 bottom-8 w-20 flex flex-col justify-between text-xs text-gray-500">
        <span>{{ formatCurrency(maxValue) }}</span>
        <span>{{ formatCurrency(maxValue * 0.75) }}</span>
        <span>{{ formatCurrency(maxValue * 0.5) }}</span>
        <span>{{ formatCurrency(maxValue * 0.25) }}</span>
        <span>$0</span>
      </div>

      <!-- Chart area -->
      <div class="ml-24 mr-16 h-full relative">
        <!-- Zero line -->
        <div
          class="absolute w-full border-t-2 border-red-300 border-dashed"
          :style="`bottom: ${getYPosition(0)}%`">
          <span
            class="absolute -right-12 -top-2 text-xs text-red-500 bg-white px-1"
            >$0</span
          >
        </div>

        <!-- Critical balance line -->
        <div
          v-if="criticalBalance > 0 && criticalBalance <= maxValue"
          class="absolute w-full border-t border-orange-400 border-dashed"
          :style="`bottom: ${getYPosition(criticalBalance)}%`">
          <span
            class="absolute -right-12 -top-2 text-xs text-orange-600 bg-white px-1"
            >Critical</span
          >
        </div>

        <!-- Cash flow line -->
        <svg
          class="w-full h-full"
          viewBox="0 0 400 240"
          preserveAspectRatio="xMidYMid meet">
          <!-- Grid lines -->
          <defs>
            <pattern
              id="grid"
              width="30.77"
              height="40"
              patternUnits="userSpaceOnUse">
              <path
                d="M 30.77 0 L 0 0 0 40"
                fill="none"
                stroke="#e5e7eb"
                stroke-width="0.5" />
            </pattern>
          </defs>
          <rect width="100%" height="100%" fill="url(#grid)" />

          <!-- Area fill -->
          <defs>
            <linearGradient
              id="cashFlowGradient"
              x1="0%"
              y1="0%"
              x2="0%"
              y2="100%">
              <stop
                offset="0%"
                style="stop-color: #3b82f6; stop-opacity: 0.3" />
              <stop
                offset="100%"
                style="stop-color: #3b82f6; stop-opacity: 0.05" />
            </linearGradient>
          </defs>

          <path :d="cashFlowPath" fill="url(#cashFlowGradient)" stroke="none" />

          <!-- Cash flow line -->
          <path
            :d="cashFlowPath"
            fill="none"
            stroke="#3b82f6"
            stroke-width="3"
            stroke-linecap="round"
            stroke-linejoin="round" />

          <!-- Data points -->
          <circle
            v-for="(point, index) in chartPoints"
            :key="index"
            :cx="point.x"
            :cy="point.y"
            r="4"
            :fill="getPointColor(point.balance)"
            stroke="white"
            stroke-width="2"
            class="cursor-pointer hover:r-6 transition-all"
            @mouseenter="showTooltip(index, $event)"
            @mouseleave="hideTooltip" />

          <!-- X-axis labels inside SVG -->
          <text
            v-for="(point, index) in xAxisLabelPoints"
            :key="`label-${index}`"
            :x="point.x"
            :y="220"
            text-anchor="middle"
            fill="#6b7280"
            font-size="10"
            font-family="system-ui, -apple-system, sans-serif">
            {{ point.label }}
          </text>
        </svg>

        <!-- Tooltip -->
        <div
          v-if="tooltip.show"
          class="absolute z-10 bg-gray-900 text-white text-xs rounded py-2 px-3 pointer-events-none"
          :style="tooltipStyle">
          <div class="font-semibold">Week {{ tooltip.week }}</div>
          <div>Balance: {{ formatCurrency(tooltip.balance) }}</div>
          <div>Cash Flow: {{ formatCurrency(tooltip.netFlow) }}</div>
          <div>{{ formatDate(tooltip.date) }}</div>
        </div>
      </div>
    </div>

    <!-- Legend -->
    <div class="flex items-center justify-center space-x-6 text-sm">
      <div class="flex items-center space-x-2">
        <div class="w-4 h-0.5 bg-blue-500"></div>
        <span class="text-gray-600">Cash Flow</span>
      </div>
      <div class="flex items-center space-x-2">
        <div class="w-4 h-0.5 border-t-2 border-red-300 border-dashed"></div>
        <span class="text-gray-600">Break Even</span>
      </div>
      <div class="flex items-center space-x-2">
        <div class="w-4 h-0.5 border-t border-orange-400 border-dashed"></div>
        <span class="text-gray-600">Critical Level</span>
      </div>
    </div>

    <!-- Summary Stats -->
    <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mt-6">
      <div class="text-center p-3 bg-blue-50 rounded-lg">
        <p class="text-sm font-medium text-blue-800">Lowest Point</p>
        <p class="text-lg font-bold text-blue-600">
          {{ formatCurrency(lowestBalance) }}
        </p>
        <p class="text-xs text-blue-600">Week {{ lowestWeek }}</p>
      </div>
      <div class="text-center p-3 bg-green-50 rounded-lg">
        <p class="text-sm font-medium text-green-800">Total Inflow</p>
        <p class="text-lg font-bold text-green-600">
          {{ formatCurrency(totalInflow) }}
        </p>
      </div>
      <div class="text-center p-3 bg-red-50 rounded-lg">
        <p class="text-sm font-medium text-red-800">Total Outflow</p>
        <p class="text-lg font-bold text-red-600">
          {{ formatCurrency(totalOutflow) }}
        </p>
      </div>
      <div class="text-center p-3 bg-purple-50 rounded-lg">
        <p class="text-sm font-medium text-purple-800">Net Change</p>
        <p class="text-lg font-bold text-purple-600">
          {{ formatCurrency(netChange) }}
        </p>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { CashFlowProjection } from "~/types/cashflow";

interface Props {
  data: CashFlowProjection[];
  criticalBalance?: number;
}

const props = withDefaults(defineProps<Props>(), {
  criticalBalance: 50000,
});

const emit = defineEmits<{
  "weeks-changed": [weeks: number];
}>();

// Week selection
const selectedWeeks = ref(13);

// Watch for changes and emit to parent
watch(selectedWeeks, (newWeeks) => {
  emit("weeks-changed", newWeeks);
});

// Reactive state for tooltip
const tooltip = ref({
  show: false,
  week: 0,
  balance: 0,
  netFlow: 0,
  date: new Date(),
  x: 0,
  y: 0,
});

// Computed properties
const startingBalance = computed(() =>
  props.data.length > 0 ? props.data[0].balance : 0
);

const endingBalance = computed(() =>
  props.data.length > 0 ? props.data[props.data.length - 1].projectedBalance : 0
);

const maxValue = computed(() => {
  const balances = props.data.map((d) =>
    Math.max(d.balance, d.projectedBalance)
  );
  const max = Math.max(...balances, props.criticalBalance);
  return Math.ceil((max * 1.1) / 10000) * 10000;
});

const minValue = computed(() => {
  const balances = props.data.map((d) =>
    Math.min(d.balance, d.projectedBalance)
  );
  return Math.min(...balances, 0);
});

const chartPoints = computed(() => {
  if (props.data.length === 0) return [];

  return props.data.map((point, index) => {
    const x =
      props.data.length === 1 ? 200 : (index / (props.data.length - 1)) * 400;
    const y = 200 - (getYPosition(point.projectedBalance) / 100) * 200;

    return {
      x,
      y,
      balance: point.projectedBalance,
      date: point.date,
      netFlow: point.netFlow,
    };
  });
});

const cashFlowPath = computed(() => {
  if (chartPoints.value.length === 0) return "";

  let path = `M ${chartPoints.value[0].x} ${chartPoints.value[0].y}`;

  for (let i = 1; i < chartPoints.value.length; i++) {
    path += ` L ${chartPoints.value[i].x} ${chartPoints.value[i].y}`;
  }

  const lastPoint = chartPoints.value[chartPoints.value.length - 1];
  const firstPoint = chartPoints.value[0];
  path += ` L ${lastPoint.x} 200 L ${firstPoint.x} 200 Z`;

  return path;
});

const xAxisLabelPoints = computed(() => {
  if (props.data.length === 0) return [];

  const maxLabels = 6;
  const step = Math.max(1, Math.floor(props.data.length / maxLabels));
  const labels = [];

  for (let i = 0; i < props.data.length; i += step) {
    const point = props.data[i];
    const x =
      props.data.length === 1 ? 200 : (i / (props.data.length - 1)) * 400;

    labels.push({
      label: point.date.toLocaleDateString("en-US", {
        month: "short",
        day: "numeric",
      }),
      x: x,
    });
  }

  if (props.data.length > 1) {
    const lastIndex = props.data.length - 1;
    const lastIncluded = labels[labels.length - 1];
    const lastX = (lastIndex / (props.data.length - 1)) * 400;

    if (Math.abs(lastIncluded.x - lastX) > 20) {
      labels.push({
        label: props.data[lastIndex].date.toLocaleDateString("en-US", {
          month: "short",
          day: "numeric",
        }),
        x: 400,
      });
    }
  }

  return labels;
});

const projectedBalanceColor = computed(() => {
  if (endingBalance.value < 0) return "text-red-600";
  if (endingBalance.value < props.criticalBalance) return "text-orange-600";
  if (endingBalance.value < startingBalance.value) return "text-yellow-600";
  return "text-green-600";
});

const lowestBalance = computed(() =>
  Math.min(...props.data.map((d) => d.projectedBalance))
);

const lowestWeek = computed(() => {
  const lowest = lowestBalance.value;
  const index = props.data.findIndex((d) => d.projectedBalance === lowest);
  return index + 1;
});

const totalInflow = computed(() =>
  props.data.reduce((sum, d) => sum + d.inflow, 0)
);

const totalOutflow = computed(() =>
  props.data.reduce((sum, d) => sum + Math.abs(d.outflow), 0)
);

const netChange = computed(() => endingBalance.value - startingBalance.value);

const tooltipStyle = computed(() => ({
  left: `${tooltip.value.x}px`,
  top: `${tooltip.value.y - 60}px`,
  transform: "translateX(-50%)",
}));

// Helper functions
const formatCurrency = (amount: number) => {
  return new Intl.NumberFormat("en-US", {
    style: "currency",
    currency: "USD",
    minimumFractionDigits: 0,
    maximumFractionDigits: 0,
  }).format(amount);
};

const formatDate = (date: Date) => {
  return new Intl.DateTimeFormat("en-US", {
    month: "short",
    day: "numeric",
    year: "numeric",
  }).format(new Date(date));
};

const getYPosition = (value: number) => {
  const range = maxValue.value - minValue.value;
  return ((value - minValue.value) / range) * 100;
};

const getPointColor = (balance: number) => {
  if (balance < 0) return "#dc2626";
  if (balance < props.criticalBalance) return "#ea580c";
  if (balance < props.criticalBalance * 1.5) return "#d97706";
  return "#059669";
};

const showTooltip = (index: number, event: MouseEvent) => {
  const point = props.data[index];
  if (point) {
    tooltip.value = {
      show: true,
      week: index + 1,
      balance: point.projectedBalance,
      netFlow: point.netFlow,
      date: point.date,
      x: event.offsetX,
      y: event.offsetY,
    };
  }
};

const hideTooltip = () => {
  tooltip.value.show = false;
};
</script>