import { useState, useCallback, useMemo } from 'react';
import type { Site } from '@/types/index.ts';
import { useSitesStore } from '@/store/sites.ts';
import { useToastStore } from '@/components/ui/Toast.tsx';
import Button from '@/components/ui/Button.tsx';
import ConfirmDialog from '@/components/ui/ConfirmDialog.tsx';
import BatchEdit from './BatchEdit.tsx';

interface SiteListProps {
  onEditSite: (site: Site) => void;
  onAddSite: () => void;
}

/** Group co-located sites (within ~10m = 0.0001°) */
function groupSites(sites: Site[]): { key: string; label: string; sites: Site[] }[] {
  const groups = new Map<string, Site[]>();
  const order: string[] = [];

  for (const site of sites) {
    // Round to 4 decimals (~11m precision)
    const key = `${site.lat.toFixed(4)},${site.lon.toFixed(4)}`;
    if (!groups.has(key)) {
      groups.set(key, []);
      order.push(key);
    }
    groups.get(key)!.push(site);
  }

  return order.map((key) => {
    const g = groups.get(key)!;
    // Extract base name from first site (strip sector suffixes)
    const baseName = g[0].name.replace(/-(Alpha|Beta|Gamma|Delta|Epsilon|Zeta|S\d+|clone)$/i, '');
    return {
      key,
      label: baseName,
      sites: g,
    };
  });
}

export default function SiteList({ onEditSite, onAddSite }: SiteListProps) {
  const sites = useSitesStore((s) => s.sites);
  const deleteSite = useSitesStore((s) => s.deleteSite);
  const selectSite = useSitesStore((s) => s.selectSite);
  const selectedSiteId = useSitesStore((s) => s.selectedSiteId);
  const isPlacingMode = useSitesStore((s) => s.isPlacingMode);
  const togglePlacingMode = useSitesStore((s) => s.togglePlacingMode);
  const selectedSiteIds = useSitesStore((s) => s.selectedSiteIds);
  const toggleSiteSelection = useSitesStore((s) => s.toggleSiteSelection);
  const selectAllSites = useSitesStore((s) => s.selectAllSites);
  const clearSelection = useSitesStore((s) => s.clearSelection);
  const cloneSector = useSitesStore((s) => s.cloneSector);
  const addToast = useToastStore((s) => s.addToast);

  const [flashIds, setFlashIds] = useState<Set<string>>(new Set());

  const triggerFlash = useCallback((ids: string[]) => {
    setFlashIds(new Set(ids));
    setTimeout(() => setFlashIds(new Set()), 700);
  }, []);

  // Delete confirmation dialog state
  const [deleteTarget, setDeleteTarget] = useState<{ id: string; name: string } | null>(null);

  const handleDeleteConfirmed = useCallback(async () => {
    if (!deleteTarget) return;
    const { id, name } = deleteTarget;

    // Snapshot the site data before deleting (for undo)
    const siteData = sites.find((s) => s.id === id);
    setDeleteTarget(null);

    await deleteSite(id);

    // Toast with undo action
    if (siteData) {
      addToast(`"${name}" deleted`, 'info', {
        duration: 10000,
        action: {
          label: 'Undo',
          onClick: async () => {
            // Restore the deleted site
            await useSitesStore.getState().addSite({
              name: siteData.name,
              lat: siteData.lat,
              lon: siteData.lon,
              height: siteData.height,
              power: siteData.power,
              gain: siteData.gain,
              frequency: siteData.frequency,
              antennaType: siteData.antennaType,
              azimuth: siteData.azimuth,
              beamwidth: siteData.beamwidth,
              color: siteData.color,
              visible: siteData.visible,
              notes: siteData.notes,
              equipment: siteData.equipment,
            });
            addToast(`"${name}" restored`, 'success');
          },
        },
      });
    }
  }, [deleteTarget, sites, deleteSite, addToast]);

  const allSelected = sites.length > 0 && selectedSiteIds.length === sites.length;

  // Group co-located sites
  const siteGroups = useMemo(() => groupSites(sites), [sites]);
  const hasGroups = siteGroups.some((g) => g.sites.length > 1);

  // Count unique locations
  const locationCount = siteGroups.length;

  const renderSiteRow = (site: Site, isGrouped: boolean) => {
    const isBatchSelected = selectedSiteIds.includes(site.id);
    const isFlashing = flashIds.has(site.id);

    return (
      <div
        key={site.id}
        className={`px-4 py-2 flex items-center gap-2.5 cursor-pointer
          hover:bg-gray-50 dark:hover:bg-dark-border/50 transition-colors
          ${selectedSiteId === site.id ? 'bg-blue-50 dark:bg-blue-900/20' : ''}
          ${isBatchSelected && selectedSiteId !== site.id ? 'bg-blue-50/50 dark:bg-blue-900/10' : ''}
          ${isFlashing ? 'flash-update' : ''}
          ${isGrouped ? 'pl-8' : ''}`}
        onClick={() => selectSite(site.id)}
      >
        {/* Batch checkbox */}
        <input
          type="checkbox"
          checked={isBatchSelected}
          onChange={() => toggleSiteSelection(site.id)}
          onClick={(e) => e.stopPropagation()}
          className="w-3.5 h-3.5 rounded border-gray-300 dark:border-dark-border accent-blue-600 flex-shrink-0"
        />

        {/* Color indicator */}
        <div
          className="w-4 h-4 rounded-full flex-shrink-0 border-2 border-white dark:border-dark-border shadow"
          style={{ backgroundColor: site.color }}
        />

        {/* Info */}
        <div className="flex-1 min-w-0">
          <div className="text-sm font-medium text-gray-800 dark:text-dark-text truncate flex items-center gap-1.5">
            {site.name}
            {/* Azimuth badge for grouped sectors */}
            {isGrouped && site.antennaType === 'sector' && (
              <span className="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-semibold bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300">
                {site.azimuth ?? 0}°
              </span>
            )}
          </div>
          <div className="text-xs text-gray-500 dark:text-dark-muted">
            {site.frequency} MHz · {site.power} dBm ·{' '}
            {site.antennaType === 'omni'
              ? 'Omni'
              : `Sector ${site.azimuth ?? 0}°`}
            {' '}· {site.height}m
          </div>
        </div>

        {/* Actions */}
        <div className="flex gap-1 flex-shrink-0">
          <button
            onClick={(e) => {
              e.stopPropagation();
              onEditSite(site);
            }}
            className="px-2 py-1 text-xs text-blue-600 dark:text-blue-400 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded min-w-[44px] min-h-[32px] flex items-center justify-center"
            title="Edit site"
          >
            Edit
          </button>
          <button
            onClick={async (e) => {
              e.stopPropagation();
              await cloneSector(site.id);
              addToast(`Added sector to "${site.name}" (+120°)`, 'success');
            }}
            className="px-2 py-1 text-xs text-purple-600 dark:text-purple-400 hover:bg-purple-50 dark:hover:bg-purple-900/20 rounded min-h-[32px] flex items-center justify-center"
            title="Add sector at same location (+120° azimuth)"
          >
            + Sector
          </button>
          <button
            onClick={(e) => {
              e.stopPropagation();
              setDeleteTarget({ id: site.id, name: site.name });
            }}
            className="px-2 py-1 text-xs text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 rounded min-w-[32px] min-h-[32px] flex items-center justify-center"
            title="Delete site"
          >
            ×
          </button>
        </div>
      </div>
    );
  };

  return (
    <div className="bg-white dark:bg-dark-surface border border-gray-200 dark:border-dark-border rounded-lg shadow-sm">
      {/* Header */}
      <div className="px-4 py-3 border-b border-gray-200 dark:border-dark-border flex items-center justify-between">
        <h2 className="text-sm font-semibold text-gray-800 dark:text-dark-text">
          Sites ({sites.length})
          {hasGroups && (
            <span className="font-normal text-gray-400 dark:text-dark-muted ml-1">
              · {locationCount} location{locationCount !== 1 ? 's' : ''}
            </span>
          )}
        </h2>
        <div className="flex gap-2">
          <Button
            size="sm"
            variant={isPlacingMode ? 'danger' : 'primary'}
            onClick={togglePlacingMode}
          >
            {isPlacingMode ? 'Cancel' : '+ Place on Map'}
          </Button>
          <Button size="sm" variant="secondary" onClick={onAddSite}>
            + Manual
          </Button>
        </div>
      </div>

      {/* Select All row */}
      {sites.length > 0 && (
        <div className="px-4 py-1.5 border-b border-gray-100 dark:border-dark-border flex items-center justify-between">
          <label className="flex items-center gap-2 cursor-pointer text-xs text-gray-500 dark:text-dark-muted">
            <input
              type="checkbox"
              checked={allSelected}
              onChange={() => (allSelected ? clearSelection() : selectAllSites())}
              className="w-3.5 h-3.5 rounded border-gray-300 dark:border-dark-border accent-blue-600"
            />
            {allSelected ? 'Deselect All' : 'Select All'}
          </label>
          {selectedSiteIds.length > 0 && (
            <span className="text-xs text-blue-600 dark:text-blue-400">
              {selectedSiteIds.length} selected
            </span>
          )}
        </div>
      )}

      {/* Batch edit panel */}
      {selectedSiteIds.length > 0 && (
        <div className="px-3 pt-3">
          <BatchEdit onBatchApplied={triggerFlash} />
        </div>
      )}

      {/* Sites list */}
      {sites.length === 0 ? (
        <div className="p-4 text-center text-sm text-gray-400 dark:text-dark-muted">
          No sites yet. Click on the map or use "+ Manual" to add one.
        </div>
      ) : (
        <div className="divide-y divide-gray-100 dark:divide-dark-border max-h-72 overflow-y-auto">
          {siteGroups.map((group) => {
            if (group.sites.length === 1) {
              // Single site — render normally
              return renderSiteRow(group.sites[0], false);
            }

            // Multi-sector group
            return (
              <div key={group.key}>
                {/* Group header */}
                <div className="px-4 py-1.5 bg-gray-50 dark:bg-dark-bg flex items-center gap-2">
                  <span className="text-xs font-semibold text-gray-500 dark:text-dark-muted">
                    {group.label}
                  </span>
                  <span className="text-[10px] px-1.5 py-0.5 rounded-full bg-purple-100 dark:bg-purple-900/30 text-purple-600 dark:text-purple-300 font-medium">
                    {group.sites.length} sectors
                  </span>
                </div>
                {/* Grouped site rows */}
                {group.sites.map((site) => renderSiteRow(site, true))}
              </div>
            );
          })}
        </div>
      )}
      {/* Delete confirmation dialog */}
      {deleteTarget && (
        <ConfirmDialog
          title="Delete Site?"
          message={`Are you sure you want to delete "${deleteTarget.name}"? This action can be undone for 10 seconds.`}
          confirmLabel="Delete"
          cancelLabel="Cancel"
          danger
          onConfirm={handleDeleteConfirmed}
          onCancel={() => setDeleteTarget(null)}
        />
      )}
    </div>
  );
}
