<template>
  <div class="space-y-6">
    <!-- Header Section -->
    <div
      class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4"
    >
      <div>
        <h1 class="text-xl md:text-2xl font-semibold text-content-primary">
          Dashboard
        </h1>
        <p class="text-sm text-content-secondary mt-1">
          Ringkasan pertumbuhan penggunaan komponen di berbagai kategori
          antarmuka.
        </p>
      </div>
      <DatePicker
        mode="range"
        :model-value="dateRangeDisplay"
        @update:model-value="
          (val) => {
            const range = val as [string, string];
            dateRange = [convertToISO(range[0]), convertToISO(range[1])] as
              | [string, string]
              | null;
          }
        "
        placeholder="Pilih Rentang Tanggal"
        date-format="dd/MM/yyyy"
        trigger-width="250px"
        size="sm"
      />
    </div>

    <!-- Metrics Cards -->
    <div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
      <div
        v-for="metric in dashboardMetrics"
        :key="metric.label"
        class="bg-white rounded-lg border border-gray-200 p-6 shadow-sm"
      >
        <div class="flex items-start justify-between">
          <div class="flex-1">
            <p class="text-sm text-content-secondary mb-1">
              {{ metric.label }}
            </p>
            <p class="text-3xl font-semibold text-content-primary mb-2">
              {{ metric.value }}
            </p>
            <div class="flex items-center space-x-2">
              <IconTrendingUp :size="20" class="text-green-600" />
              <span class="text-sm text-green-600">{{ metric.subtitle }}</span>
            </div>
          </div>
          <div
            :class="[
              'p-2 md:p-3 rounded-lg',
              metric.iconColor === 'orange'
                ? 'bg-orange-500 text-white'
                : metric.iconColor === 'blue'
                  ? 'bg-guide-500 text-white'
                  : 'bg-green-500 text-white',
            ]"
          >
            <component :is="getIcon(metric.icon)" :size="24" />
          </div>
        </div>
      </div>
    </div>

    <!-- Chart Section -->
    <div class="bg-white rounded-lg border border-gray-200 p-6 shadow-sm">
      <div class="mb-6">
        <h2 class="text-lg font-semibold text-content-primary mb-1">
          Tren Adopsi Komponen Per Kategori
        </h2>
      </div>
      <div
        class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6"
      >
        <ButtonGroup
          :options="periodOptions"
          :model-value="selectedPeriod"
          @update:model-value="(val) => (selectedPeriod = val)"
        />
        <DatePicker
          mode="single"
          :model-value="dateDisplay"
          @update:model-value="
            (val) => {
              const date = val as string;
              selectedDate = date ? convertToISO(date) : null;
            }
          "
          placeholder="Pilih Tanggal"
          date-format="dd/MM/yyyy"
          trigger-width="200px"
          size="sm"
        />
      </div>
      <component
        v-if="VueApexChart"
        :is="VueApexChart"
        :key="`bar-chart-${selectedPeriod}`"
        type="bar"
        :height="350"
        :series="chartBarSeries"
        :options="chartBarOptions"
      />
      <div
        v-else
        class="h-[350px] flex items-center justify-center text-gray-500"
      >
        Loading chart...
      </div>
    </div>

    <!-- Table Section -->
    <div class="bg-white rounded-lg border border-gray-200 p-6 shadow-sm">
      <div
        class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-4"
      >
        <TextField
          :model-value="searchTerm"
          @update:model-value="(val) => (searchTerm = val as string)"
          placeholder="Search..."
          :prefix-icon="IconSearch"
          class="flex-1 max-w-md"
        />
        <div class="flex flex-wrap items-center gap-2">
          <SelectDropdown
            :options="statusOptions"
            :model-value="statusFilter"
            @update:model-value="
              (val) => (statusFilter = val === 'all' ? null : (val as string))
            "
            placeholder="Status"
            size="sm"
            width="150px"
          />
          <SelectDropdown
            :options="progressOptions"
            :model-value="progressFilter"
            @update:model-value="
              (val) => (progressFilter = val === 'all' ? null : (val as string))
            "
            placeholder="Progress"
            size="sm"
            width="150px"
          />
          <SelectDropdown
            :options="instansiOptions"
            :model-value="instansiFilter"
            @update:model-value="
              (val) => (instansiFilter = val === 'all' ? null : (val as string))
            "
            placeholder="Instansi"
            size="sm"
            width="150px"
          />
        </div>
      </div>
      <Table
        :columns="tableColumnsConfig"
        :fetchData="fetchData"
        :initialPageSize="10"
        :pageSizeOptions="[10, 20, 30, 50]"
        :showSearch="false"
        rowKey="id"
        :selectable="true"
      />
    </div>

    <!-- Update Drawer Content -->
    <Drawer
      v-model="isDrawerOpen"
      :title="selectedRow?.fullName || 'Detail Instansi'"
      position="right"
      width="md"
    >
      <div v-if="selectedRow" class="space-y-6">
        <div class="flex items-center gap-4">
          <Avatar
            :src="selectedRow.logo"
            :alt="selectedRow.name"
            :size="48"
            :initials="getInitials(selectedRow.name)"
            shape="circle"
          />
          <div>
            <h3 class="text-lg font-semibold text-content-primary">
              {{ selectedRow.fullName }}
            </h3>
            <p v-if="selectedRow.nameSubtext" class="text-sm text-gray-500">
              {{ selectedRow.nameSubtext }}
            </p>
          </div>
        </div>

        <div class="grid grid-cols-2 gap-4">
          <div class="p-4 bg-gray-50 rounded-lg">
            <p class="text-xs text-content-secondary mb-1">Status</p>
            <Badge
              :variant="getStatusBadgeVariant(selectedRow.status)"
              type="soft"
              size="md"
            >
              {{ selectedRow.status }}
            </Badge>
          </div>
          <div class="p-4 bg-gray-50 rounded-lg">
            <p class="text-xs text-content-secondary mb-1">Progress</p>
            <div class="flex items-center gap-2">
              <span class="text-xl font-semibold"
                >{{ selectedRow.progress }}%</span
              >
            </div>
          </div>
          <div class="col-span-2 p-4 bg-gray-50 rounded-lg">
            <p class="text-xs text-content-secondary mb-1">
              Estimasi Efisiensi
            </p>
            <p class="text-xl font-semibold text-content-primary">
              {{ selectedRow.estimasiEfisiensi }}
            </p>
          </div>
        </div>
      </div>
    </Drawer>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, h, watch } from 'vue';
import {
  IconBrandAppleArcade,
  IconFile,
  IconVector,
  IconTrendingUp,
  IconSearch,
} from '@tabler/icons-vue';
import {
  Table,
  Badge,
  Tooltip,
  DatePicker,
  SelectDropdown,
  TextField,
  ButtonGroup,
  Drawer,
  CircleProgressBar,
  Avatar,
  Button,
  type Column,
} from '@idds/vue';
import type { FetchParams } from '@idds/vue';
import { dashboardMetrics } from '../data/dashboardMetrics';
import {
  fetchDashboardTableDataNew,
  type DashboardTableRowNew,
  statusFilterOptions,
  progressFilterOptions,
  instansiFilterOptions,
} from '../data/tableDataNew';
import {
  defaultChartBarData,
  filterChartBarDataByPeriod,
  chartBarCategories,
} from '../data/chartBarData';

function getBrandColors(): string[] {
  return ['#A1C4F5', '#196BCD', '#0968F6', '#022A5B', '#041225', '#C0D7F9'];
}

const iconMap = {
  package: IconBrandAppleArcade,
  document: IconFile,
  'check-square': IconVector,
};

const VueApexChart = ref<any>(null);
const brandColors = ref<string[]>([]);
const dateRange = ref<[string, string] | null>(null);
const selectedDate = ref<string | null>(null);
const selectedPeriod = ref<string | number>('1-bulan');
const searchTerm = ref<string>('');
const statusFilter = ref<string | null>(null);
const progressFilter = ref<string | null>(null);
const instansiFilter = ref<string | null>(null);
const isDrawerOpen = ref(false);
const selectedRow = ref<DashboardTableRowNew | null>(null);

const handleDetailClick = (row: DashboardTableRowNew) => {
  selectedRow.value = row;
  isDrawerOpen.value = true;
};

// Convert date format from dd/MM/yyyy to YYYY-MM-DD
const convertToISO = (dateStr: string): string => {
  if (!dateStr) return '';
  const parts = dateStr.split('/');
  if (parts.length === 3) {
    return `${parts[2]}-${parts[1]}-${parts[0]}`;
  }
  return dateStr;
};

// Convert date format from YYYY-MM-DD to dd/MM/yyyy
const convertToDisplay = (dateStr: string): string => {
  if (!dateStr) return '';
  const date = new Date(dateStr);
  if (isNaN(date.getTime())) return dateStr;
  const day = String(date.getDate()).padStart(2, '0');
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const year = date.getFullYear();
  return `${day}/${month}/${year}`;
};

// Convert dateRange to display format for DatePicker
const dateRangeDisplay = computed(() => {
  if (!dateRange.value || !dateRange.value[0] || !dateRange.value[1]) {
    return ['', ''] as [string, string];
  }
  return [
    convertToDisplay(dateRange.value[0]),
    convertToDisplay(dateRange.value[1]),
  ] as [string, string];
});

const dateDisplay = computed(() => {
  if (!selectedDate.value) return '';
  return convertToDisplay(selectedDate.value);
});

// Filter chart data berdasarkan periode
const chartBarData = computed(() => {
  return filterChartBarDataByPeriod(
    defaultChartBarData,
    selectedPeriod.value as '1-tahun' | '1-bulan' | '7-hari',
  );
});

const chartBarSeries = computed(() => [
  {
    name: 'Adopsi',
    data: chartBarData.value.map((point) => point.value),
  },
]);

const chartBarOptions = computed(() => ({
  chart: {
    id: 'dashboard-bar-chart',
    type: 'bar',
    toolbar: { show: false },
  },
  xaxis: {
    categories: chartBarCategories,
  },
  yaxis: {
    labels: {
      formatter: (val: number) => `${val}x`,
    },
  },
  plotOptions: {
    bar: {
      borderRadius: 4,
      columnWidth: '60%',
      distributed: true,
    },
  },
  dataLabels: {
    enabled: false,
  },
  colors: brandColors.value.length > 0 ? brandColors.value : ['#3b82f6'],
  legend: {
    show: true,
    position: 'bottom',
    showForSingleSeries: true,
  },
}));

const getIcon = (iconName: string) => {
  return iconMap[iconName as keyof typeof iconMap] || IconBrandAppleArcade;
};

// ButtonGroup options untuk periode
const periodOptions = [
  { value: '1-tahun', label: '1 Tahun' },
  { value: '1-bulan', label: '1 Bulan' },
  { value: '7-hari', label: '7 Hari' },
];

// Status options untuk filter
const statusOptions = statusFilterOptions;
const progressOptions = progressFilterOptions;
const instansiOptions = instansiFilterOptions;

// Helper untuk mendapatkan warna badge status
const getStatusBadgeVariant = (
  status: DashboardTableRowNew['status'],
): 'success' | 'error' | 'warning' | 'neutral' => {
  switch (status) {
    case 'Sangat Baik':
      return 'success';
    case 'Baik':
      return 'neutral';
    case 'Cukup':
      return 'warning';
    case 'Kurang':
      return 'error';
    default:
      return 'neutral';
  }
};

const getInitials = (name: string) => {
  return name
    .split(' ')
    .map((word) => word[0])
    .join('')
    .slice(0, 2)
    .toUpperCase();
};

// Helper untuk mendapatkan warna progress
const getProgressColor = (progress: number): string => {
  if (progress >= 76) return 'text-green-600';
  if (progress >= 51) return 'text-blue-600';
  if (progress >= 26) return 'text-orange-600';
  return 'text-red-600';
};

// Table columns configuration
const tableColumnsConfig: Column[] = [
  {
    header: 'Nama',
    accessor: 'name',
    sortable: true,
    render: (row: DashboardTableRowNew) =>
      h('div', { class: 'flex items-center gap-3 text-xs' }, [
        h(Avatar, {
          src: row.logo,
          alt: row.name,
          size: 32,
          initials: getInitials(row.name),
          shape: 'circle',
        }),
        h('div', { class: 'flex flex-col max-w-[96px] sm:max-w-none' }, [
          h(
            'div',
            {
              class: 'font-medium text-content-primary truncate',
              title: row.name,
            },
            row.name,
          ),
          row.nameSubtext
            ? h(
                'div',
                {
                  class:
                    'text-[10px] sm:text-xs text-gray-500 truncate max-w-[120px]',
                  title: row.nameSubtext,
                },
                row.nameSubtext,
              )
            : null,
        ]),
      ]),
  },
  {
    header: 'Progress',
    accessor: 'progress',
    sortable: true,
    render: (row: DashboardTableRowNew) => {
      let variant = 'negative';
      if (row.progress >= 76) variant = 'positive';
      else if (row.progress >= 51) variant = 'primary';
      else if (row.progress >= 26) variant = 'warning';

      return h('div', { class: 'flex items-center gap-2 pl-4 sm:pl-0' }, [
        h(CircleProgressBar, {
          progress: row.progress,
          diameter: 20,
          strokeWidth: 3,
          variant: variant,
        }),
        h(
          'span',
          {
            class: `text-xs font-medium ${getProgressColor(row.progress)}`,
          },
          `${row.progress}%`,
        ),
      ]);
    },
  },
  {
    header: 'Status',
    accessor: 'status',
    sortable: true,
    render: (row: DashboardTableRowNew) =>
      h(
        Badge,
        {
          variant: getStatusBadgeVariant(row.status),
          type: 'soft',
          size: 'sm',
        },
        () => row.status,
      ),
  },
  {
    header: 'Estimasi Efisiensi',
    accessor: 'estimasiEfisiensi',
    sortable: true,
    render: (row: DashboardTableRowNew) =>
      h('span', { class: 'text-sm text-gray-700' }, row.estimasiEfisiensi),
  },
  {
    header: 'Aksi',
    accessor: 'actions',
    sortable: false,
    render: (row: DashboardTableRowNew) =>
      h(Tooltip, { title: 'Lihat Detail', placement: 'top' }, () =>
        h(
          Button,
          {
            hierarchy: 'secondary',
            size: 'sm',
            onClick: () => handleDetailClick(row),
          },
          () => 'Lihat Detail',
        ),
      ),
  },
];

// Fetch function untuk table dengan filters
const fetchData = ref((params: FetchParams) => {
  return fetchDashboardTableDataNew({
    ...params,
    searchTerm: searchTerm.value || params.searchTerm,
    statusFilter: statusFilter.value,
    progressFilter: progressFilter.value,
    instansiFilter: instansiFilter.value,
  });
});

watch(
  [searchTerm, statusFilter, progressFilter, instansiFilter],
  () => {
    fetchData.value = (params: FetchParams) => {
      return fetchDashboardTableDataNew({
        ...params,
        searchTerm: searchTerm.value || params.searchTerm,
        statusFilter: statusFilter.value,
        progressFilter: progressFilter.value,
        instansiFilter: instansiFilter.value,
      });
    };
  },
  { deep: true },
);

onMounted(() => {
  if (typeof window !== 'undefined') {
    import('vue3-apexcharts')
      .then((chartModule) => {
        VueApexChart.value = (chartModule as any).default || chartModule;
      })
      .catch((error) => {
        console.error('Failed to load chart component:', error);
      });

    // Initialize brand colors
    const colors = getBrandColors();
    brandColors.value = [...colors];
  }
});
</script>
