import { useEffect, useState, useCallback } from 'react';
import { useNavigate, useSearchParams, Link } from 'react-router-dom';
import { clsx } from 'clsx';
import { searchApplications, getReferenceData } from '../services/api';
import { useSearchStore } from '../stores/searchStore';
import { useNavigationStore } from '../stores/navigationStore';
import type { ApplicationListItem, SearchResult, ReferenceValue, ApplicationStatus } from '../types';

const ALL_STATUSES: ApplicationStatus[] = [
  'In Production',
  'Implementation',
  'Proof of Concept',
  'End of support',
  'End of life',
  'Deprecated',
  'Shadow IT',
  'Closed',
  'Undefined',
];

export default function ApplicationList() {
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const {
    filters,
    currentPage,
    pageSize,
    setSearchText,
    setStatuses,
    setApplicationFunction,
    setGovernanceModel,
    setApplicationSubteam,
    setApplicationType,
    setOrganisation,
    setHostingType,
    setBusinessImportance,
    setCurrentPage,
    resetFilters,
  } = useSearchStore();
  const { setNavigationContext } = useNavigationStore();

  const [result, setResult] = useState<SearchResult | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [organisations, setOrganisations] = useState<ReferenceValue[]>([]);
  const [hostingTypes, setHostingTypes] = useState<ReferenceValue[]>([]);
  const [businessImportanceOptions, setBusinessImportanceOptions] = useState<ReferenceValue[]>([]);
  const [applicationSubteams, setApplicationSubteams] = useState<ReferenceValue[]>([]);
  const [showFilters, setShowFilters] = useState(true);

  // Sync URL params with store on mount
  useEffect(() => {
    const pageParam = searchParams.get('page');
    if (pageParam) {
      const page = parseInt(pageParam, 10);
      if (!isNaN(page) && page > 0 && page !== currentPage) {
        setCurrentPage(page);
      }
    }
  }, []); // Only run on mount

  // Update URL when page changes
  useEffect(() => {
    const currentUrlPage = searchParams.get('page');
    const currentUrlPageNum = currentUrlPage ? parseInt(currentUrlPage, 10) : 1;

    if (currentPage !== currentUrlPageNum) {
      if (currentPage === 1) {
        // Remove page param when on page 1
        searchParams.delete('page');
      } else {
        searchParams.set('page', currentPage.toString());
      }
      setSearchParams(searchParams, { replace: true });
    }
  }, [currentPage, searchParams, setSearchParams]);

  const fetchApplications = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const data = await searchApplications(filters, currentPage, pageSize);
      setResult(data);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load applications');
    } finally {
      setLoading(false);
    }
  }, [filters, currentPage, pageSize]);

  useEffect(() => {
    fetchApplications();
  }, [fetchApplications]);

  useEffect(() => {
    async function loadReferenceData() {
      try {
        const data = await getReferenceData();
        setOrganisations(data.organisations);
        setHostingTypes(data.hostingTypes);
        setBusinessImportanceOptions(data.businessImportance || []);
        setApplicationSubteams(data.applicationSubteams || []);
      } catch (err) {
        console.error('Failed to load reference data', err);
      }
    }
    loadReferenceData();
  }, []);

  // Update navigation context whenever results change, so "Opslaan & Volgende" works
  // even when user opens an application in a new tab
  useEffect(() => {
    if (result && result.applications.length > 0) {
      const allIds = result.applications.map((a) => a.id);
      // Preserve current index if it's still valid, otherwise reset to 0
      setNavigationContext(allIds, filters, 0);
    }
  }, [result, filters, setNavigationContext]);

  const handleRowClick = (app: ApplicationListItem, index: number, event: React.MouseEvent) => {
    // Update current index in navigation context
    if (result) {
      const allIds = result.applications.map((a) => a.id);
      setNavigationContext(allIds, filters, index);
    }

    // Let the browser handle CTRL+click / CMD+click / middle-click natively for new tab
    // Only navigate programmatically for regular clicks
    if (!event.ctrlKey && !event.metaKey && !event.shiftKey && event.button === 0) {
      event.preventDefault();
      navigate(`/application/${app.id}`);
    }
  };

  const toggleStatus = (status: ApplicationStatus) => {
    const current = filters.statuses || [];
    if (current.includes(status)) {
      setStatuses(current.filter((s) => s !== status));
    } else {
      setStatuses([...current, status]);
    }
  };

  return (
    <div className="space-y-6">
      {/* Page header */}
      <div className="flex justify-between items-center">
        <div>
          <h2 className="text-2xl font-bold text-gray-900">Applicaties</h2>
          <p className="text-gray-600">Zoek en classificeer applicatiecomponenten</p>
        </div>
        <button
          onClick={() => setShowFilters(!showFilters)}
          className="btn btn-secondary"
        >
          {showFilters ? 'Verberg filters' : 'Toon filters'}
        </button>
      </div>

      {/* Search and filters */}
      <div className="card">
        {/* Search bar */}
        <div className="p-4 border-b border-gray-200">
          <div className="relative">
            <input
              type="text"
              placeholder="Zoeken op naam, beschrijving, leverancier..."
              value={filters.searchText || ''}
              onChange={(e) => setSearchText(e.target.value)}
              className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
            />
            <svg
              className="absolute left-3 top-2.5 h-5 w-5 text-gray-400"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
              />
            </svg>
          </div>
        </div>

        {/* Filters */}
        {showFilters && (
          <div className="p-4 bg-gray-50 border-b border-gray-200">
            <div className="flex justify-between items-center mb-4">
              <h3 className="font-medium text-gray-900">Filters</h3>
              <button
                onClick={resetFilters}
                className="text-sm text-blue-600 hover:text-blue-800"
              >
                Wis alle filters
              </button>
            </div>

            <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
              {/* Status filter */}
              <div>
                <label className="label mb-2">Status</label>
                <div className="space-y-1 max-h-48 overflow-y-auto">
                  {ALL_STATUSES.map((status) => (
                    <label key={status} className="flex items-center space-x-2">
                      <input
                        type="checkbox"
                        checked={(filters.statuses || []).includes(status)}
                        onChange={() => toggleStatus(status)}
                        className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                      />
                      <span className="text-sm text-gray-700">{status}</span>
                    </label>
                  ))}
                </div>
              </div>

              {/* Classification filters */}
              <div className="space-y-4">
                <div>
                  <label className="label mb-2">ApplicationFunction</label>
                  <div className="space-y-1">
                    {(['all', 'filled', 'empty'] as const).map((value) => (
                      <label key={value} className="flex items-center space-x-2">
                        <input
                          type="radio"
                          name="applicationFunction"
                          checked={filters.applicationFunction === value}
                          onChange={() => setApplicationFunction(value)}
                          className="border-gray-300 text-blue-600 focus:ring-blue-500"
                        />
                        <span className="text-sm text-gray-700">
                          {value === 'all' ? 'Alle' : value === 'filled' ? 'Ingevuld' : 'Leeg'}
                        </span>
                      </label>
                    ))}
                  </div>
                </div>

                <div>
                  <label className="label mb-2">Governance Model</label>
                  <div className="space-y-1">
                    {(['all', 'filled', 'empty'] as const).map((value) => (
                      <label key={value} className="flex items-center space-x-2">
                        <input
                          type="radio"
                          name="governanceModel"
                          checked={filters.governanceModel === value}
                          onChange={() => setGovernanceModel(value)}
                          className="border-gray-300 text-blue-600 focus:ring-blue-500"
                        />
                        <span className="text-sm text-gray-700">
                          {value === 'all' ? 'Alle' : value === 'filled' ? 'Ingevuld' : 'Leeg'}
                        </span>
                      </label>
                    ))}
                  </div>
                </div>

                <div>
                  <label className="label mb-2">Application Type</label>
                  <div className="space-y-1">
                    {(['all', 'filled', 'empty'] as const).map((value) => (
                      <label key={value} className="flex items-center space-x-2">
                        <input
                          type="radio"
                          name="applicationType"
                          checked={filters.applicationType === value}
                          onChange={() => setApplicationType(value)}
                          className="border-gray-300 text-blue-600 focus:ring-blue-500"
                        />
                        <span className="text-sm text-gray-700">
                          {value === 'all' ? 'Alle' : value === 'filled' ? 'Ingevuld' : 'Leeg'}
                        </span>
                      </label>
                    ))}
                  </div>
                </div>
              </div>

              {/* Dropdown filters */}
              <div className="space-y-4">
                <div>
                  <label className="label mb-2">Organisatie</label>
                  <select
                    value={filters.organisation || ''}
                    onChange={(e) => setOrganisation(e.target.value || undefined)}
                    className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                  >
                    <option value="">Alle organisaties</option>
                    {organisations.map((org) => (
                      <option key={org.objectId} value={org.name}>
                        {org.name}
                      </option>
                    ))}
                  </select>
                </div>

                <div>
                  <label className="label mb-2">Hosting Type</label>
                  <select
                    value={filters.hostingType || ''}
                    onChange={(e) => setHostingType(e.target.value || undefined)}
                    className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                  >
                    <option value="">Alle types</option>
                    {hostingTypes.map((type) => (
                      <option key={type.objectId} value={type.name}>
                        {type.name}
                      </option>
                    ))}
                  </select>
                </div>

                <div>
                  <label className="label mb-2">Business Importance</label>
                  <select
                    value={filters.businessImportance || ''}
                    onChange={(e) => setBusinessImportance(e.target.value || undefined)}
                    className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                  >
                    <option value="">Alle</option>
                    {businessImportanceOptions.map((importance) => (
                      <option key={importance.objectId} value={importance.name}>
                        {importance.name}
                      </option>
                    ))}
                  </select>
                </div>

                <div>
                  <label className="label mb-2">Subteam</label>
                  <select
                    value={filters.applicationSubteam || 'all'}
                    onChange={(e) => setApplicationSubteam(e.target.value as 'all' | 'empty' | string)}
                    className="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                  >
                    <option value="all">Alle</option>
                    <option value="empty">Leeg</option>
                    {applicationSubteams.map((subteam) => (
                      <option key={subteam.objectId} value={subteam.name}>
                        {subteam.name}
                      </option>
                    ))}
                  </select>
                </div>
              </div>
            </div>
          </div>
        )}

        {/* Results count */}
        <div className="px-4 py-3 bg-white border-b border-gray-200 flex justify-between items-center">
          <span className="text-sm text-gray-600">
            {result ? (
              <>
                Resultaten: <strong>{result.totalCount}</strong> applicaties
              </>
            ) : (
              'Laden...'
            )}
          </span>
        </div>

        {/* Results table */}
        {loading ? (
          <div className="flex items-center justify-center h-64">
            <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600" />
          </div>
        ) : error ? (
          <div className="p-4 text-red-600">{error}</div>
        ) : (
          <div className="overflow-x-auto">
            <table className="min-w-full divide-y divide-gray-200">
              <thead className="bg-gray-50">
                <tr>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    #
                  </th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    Naam
                  </th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    Status
                  </th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    AppFunctie
                  </th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    Governance
                  </th>
                  <th className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                    Benodigde inspanning
                  </th>
                </tr>
              </thead>
              <tbody className="bg-white divide-y divide-gray-200">
                {result?.applications.map((app, index) => (
                  <tr
                    key={app.id}
                    className="hover:bg-blue-50 transition-colors group"
                  >
                    <td className="py-0">
                      <Link
                        to={`/application/${app.id}`}
                        onClick={(e) => handleRowClick(app, index, e)}
                        className="block px-4 py-3 text-sm text-gray-500"
                      >
                        {(currentPage - 1) * pageSize + index + 1}
                      </Link>
                    </td>
                    <td className="py-0">
                      <Link
                        to={`/application/${app.id}`}
                        onClick={(e) => handleRowClick(app, index, e)}
                        className="block px-4 py-3"
                      >
                        <div className="text-sm font-medium text-blue-600 group-hover:text-blue-800 group-hover:underline">
                          {app.name}
                        </div>
                        <div className="text-xs text-gray-500">{app.key}</div>
                      </Link>
                    </td>
                    <td className="py-0">
                      <Link
                        to={`/application/${app.id}`}
                        onClick={(e) => handleRowClick(app, index, e)}
                        className="block px-4 py-3"
                      >
                        <StatusBadge status={app.status} />
                      </Link>
                    </td>
                    <td className="py-0">
                      <Link
                        to={`/application/${app.id}`}
                        onClick={(e) => handleRowClick(app, index, e)}
                        className="block px-4 py-3"
                      >
                        {app.applicationFunctions && app.applicationFunctions.length > 0 ? (
                          <div className="flex flex-wrap gap-1">
                            {app.applicationFunctions.map((func) => (
                              <span
                                key={func.objectId}
                                className="inline-block px-2 py-0.5 text-xs bg-blue-100 text-blue-800 rounded"
                                title={func.description || func.name}
                              >
                                {func.name}{func.applicationFunctionCategory ? ` (${func.applicationFunctionCategory.name})` : ''}
                              </span>
                            ))}
                          </div>
                        ) : (
                          <span className="text-sm text-orange-600 font-medium">
                            Leeg
                          </span>
                        )}
                      </Link>
                    </td>
                    <td className="py-0">
                      <Link
                        to={`/application/${app.id}`}
                        onClick={(e) => handleRowClick(app, index, e)}
                        className="block px-4 py-3"
                      >
                        {app.governanceModel ? (
                          <span className="text-sm text-gray-900">
                            {app.governanceModel.name}
                          </span>
                        ) : (
                          <span className="text-sm text-orange-600 font-medium">
                            Leeg
                          </span>
                        )}
                      </Link>
                    </td>
                    <td className="py-0">
                      <Link
                        to={`/application/${app.id}`}
                        onClick={(e) => handleRowClick(app, index, e)}
                        className="block px-4 py-3 text-sm text-gray-900"
                      >
                        {app.requiredEffortApplicationManagement !== null ? (
                          <span className="font-medium">
                            {app.requiredEffortApplicationManagement.toFixed(2)} FTE
                          </span>
                        ) : (
                          <span className="text-gray-400">-</span>
                        )}
                      </Link>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}

        {/* Pagination */}
        {result && result.totalPages > 1 && (
          <div className="px-4 py-3 bg-gray-50 border-t border-gray-200 flex items-center justify-between">
            {currentPage > 1 ? (
              <Link
                to={currentPage === 2 ? '/application/overview' : `/application/overview?page=${currentPage - 1}`}
                onClick={() => setCurrentPage(currentPage - 1)}
                className="btn btn-secondary"
              >
                Vorige
              </Link>
            ) : (
              <button disabled className="btn btn-secondary opacity-50 cursor-not-allowed">
                Vorige
              </button>
            )}
            <span className="text-sm text-gray-600">
              Pagina {currentPage} van {result.totalPages}
            </span>
            {currentPage < result.totalPages ? (
              <Link
                to={`/application/overview?page=${currentPage + 1}`}
                onClick={() => setCurrentPage(currentPage + 1)}
                className="btn btn-secondary"
              >
                Volgende
              </Link>
            ) : (
              <button disabled className="btn btn-secondary opacity-50 cursor-not-allowed">
                Volgende
              </button>
            )}
          </div>
        )}
      </div>
    </div>
  );
}

export function StatusBadge({ status }: { status: string | null }) {
  const statusColors: Record<string, string> = {
    'Closed': 'badge-dark-red',
    'Deprecated': 'badge-yellow',
    'End of life': 'badge-light-red',
    'End of support': 'badge-light-red',
    'Implementation': 'badge-blue',
    'In Production': 'badge-dark-green',
    'Proof of Concept': 'badge-light-green',
    'Shadow IT': 'badge-black',
    'Undefined': 'badge-gray',
  };

  if (!status) return <span className="text-sm text-gray-400">-</span>;

  return (
    <span className={clsx('badge', statusColors[status] || 'badge-gray')}>
      {status}
    </span>
  );
}

export function BusinessImportanceBadge({ importance }: { importance: string | null }) {
  // Helper function to get the number prefix from the importance string
  const getImportanceNumber = (value: string | null): string | null => {
    if (!value) return null;
    // Match patterns like "0 - Critical Infrastructure" or just "0"
    const match = value.match(/^(\d+)/);
    return match ? match[1] : null;
  };

  const importanceNumber = getImportanceNumber(importance);

  // Map importance number to icon type and color
  const getImportanceConfig = (num: string | null) => {
    switch (num) {
      case '0':
        return {
          icon: 'warning',
          color: 'badge-darker-red',
          label: importance || '0 - Critical Infrastructure',
        };
      case '1':
        return {
          icon: 'exclamation',
          color: 'badge-dark-red',
          label: importance || '1 - Critical',
        };
      case '2':
        return {
          icon: 'exclamation',
          color: 'badge-red',
          label: importance || '2 - Highest',
        };
      case '3':
        return {
          icon: 'circle',
          color: 'badge-yellow-orange',
          label: importance || '3 - High',
        };
      case '4':
        return {
          icon: 'circle',
          color: 'badge-dark-blue',
          label: importance || '4 - Medium',
        };
      case '5':
        return {
          icon: 'circle',
          color: 'badge-light-blue',
          label: importance || '5 - Low',
        };
      case '6':
        return {
          icon: 'circle',
          color: 'badge-lighter-blue',
          label: importance || '6 - Lowest',
        };
      case '9':
        return {
          icon: 'question',
          color: 'badge-black',
          label: importance || '9 - Unknown',
        };
      default:
        return {
          icon: null,
          color: 'badge-gray',
          label: importance || '-',
        };
    }
  };

  if (!importance) return <span className="text-sm text-gray-400">-</span>;

  const config = getImportanceConfig(importanceNumber);

  // Icon components
  const WarningIcon = () => (
    <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
      <path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
    </svg>
  );

  const ExclamationIcon = () => (
    <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
      <path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
    </svg>
  );

  const CircleIcon = () => (
    <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
      <circle cx="10" cy="10" r="8" />
    </svg>
  );

  const QuestionIcon = () => (
    <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
      <path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z" clipRule="evenodd" />
    </svg>
  );

  const renderIcon = () => {
    switch (config.icon) {
      case 'warning':
        return <WarningIcon />;
      case 'exclamation':
        return <ExclamationIcon />;
      case 'circle':
        return <CircleIcon />;
      case 'question':
        return <QuestionIcon />;
      default:
        return null;
    }
  };

  return (
    <span className={clsx('badge inline-flex items-center gap-1.5', config.color)}>
      {renderIcon()}
      <span>{config.label}</span>
    </span>
  );
}
