import { useState, useEffect, useCallback } from 'react';
import { useParams, Link, useSearchParams, useNavigate } from 'react-router-dom';
import { Project, Package, PaginatedResponse } from '../types';
import { getProject, listPackages, createPackage } from '../api';
import { Breadcrumb } from '../components/Breadcrumb';
import { Badge } from '../components/Badge';
import { SearchInput } from '../components/SearchInput';
import { SortDropdown, SortOption } from '../components/SortDropdown';
import { FilterChip, FilterChipGroup } from '../components/FilterChip';
import { Pagination } from '../components/Pagination';
import './Home.css';

const SORT_OPTIONS: SortOption[] = [
  { value: 'name', label: 'Name' },
  { value: 'created_at', label: 'Created' },
  { value: 'updated_at', label: 'Updated' },
];

const FORMAT_OPTIONS = ['generic', 'npm', 'pypi', 'docker', 'deb', 'rpm', 'maven', 'nuget', 'helm'];

function formatBytes(bytes: number): string {
  if (bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
}

function ProjectPage() {
  const { projectName } = useParams<{ projectName: string }>();
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();

  const [project, setProject] = useState<Project | null>(null);
  const [packagesData, setPackagesData] = useState<PaginatedResponse<Package> | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [newPackage, setNewPackage] = useState({ name: '', description: '', format: 'generic', platform: 'any' });
  const [creating, setCreating] = useState(false);

  // Get params from URL
  const page = parseInt(searchParams.get('page') || '1', 10);
  const search = searchParams.get('search') || '';
  const sort = searchParams.get('sort') || 'name';
  const order = (searchParams.get('order') || 'asc') as 'asc' | 'desc';
  const format = searchParams.get('format') || '';

  const updateParams = useCallback(
    (updates: Record<string, string | undefined>) => {
      const newParams = new URLSearchParams(searchParams);
      Object.entries(updates).forEach(([key, value]) => {
        if (value === undefined || value === '' || (key === 'page' && value === '1')) {
          newParams.delete(key);
        } else {
          newParams.set(key, value);
        }
      });
      setSearchParams(newParams);
    },
    [searchParams, setSearchParams]
  );

  const loadData = useCallback(async () => {
    if (!projectName) return;

    try {
      setLoading(true);
      const [projectData, packagesResult] = await Promise.all([
        getProject(projectName),
        listPackages(projectName, { page, search, sort, order, format: format || undefined }),
      ]);
      setProject(projectData);
      setPackagesData(packagesResult);
      setError(null);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load data');
    } finally {
      setLoading(false);
    }
  }, [projectName, page, search, sort, order, format]);

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

  // Keyboard navigation - go back with backspace
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Backspace' && !['INPUT', 'TEXTAREA'].includes((e.target as HTMLElement).tagName)) {
        e.preventDefault();
        navigate('/');
      }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [navigate]);

  async function handleCreatePackage(e: React.FormEvent) {
    e.preventDefault();
    try {
      setCreating(true);
      await createPackage(projectName!, newPackage);
      setNewPackage({ name: '', description: '', format: 'generic', platform: 'any' });
      setShowForm(false);
      loadData();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to create package');
    } finally {
      setCreating(false);
    }
  }

  const handleSearchChange = (value: string) => {
    updateParams({ search: value, page: '1' });
  };

  const handleSortChange = (newSort: string, newOrder: 'asc' | 'desc') => {
    updateParams({ sort: newSort, order: newOrder, page: '1' });
  };

  const handleFormatChange = (value: string) => {
    updateParams({ format: value, page: '1' });
  };

  const handlePageChange = (newPage: number) => {
    updateParams({ page: String(newPage) });
  };

  const clearFilters = () => {
    setSearchParams({});
  };

  const hasActiveFilters = search !== '' || format !== '';
  const packages = packagesData?.items || [];
  const pagination = packagesData?.pagination;

  if (loading && !packagesData) {
    return <div className="loading">Loading...</div>;
  }

  if (!project) {
    return <div className="error-message">Project not found</div>;
  }

  return (
    <div className="home">
      <Breadcrumb
        items={[
          { label: 'Projects', href: '/' },
          { label: project.name },
        ]}
      />

      <div className="page-header">
        <div className="page-header__info">
          <div className="page-header__title-row">
            <h1>{project.name}</h1>
            <Badge variant={project.is_public ? 'public' : 'private'}>
              {project.is_public ? 'Public' : 'Private'}
            </Badge>
          </div>
          {project.description && <p className="description">{project.description}</p>}
          <div className="page-header__meta">
            <span className="meta-item">Created {new Date(project.created_at).toLocaleDateString()}</span>
            {project.updated_at !== project.created_at && (
              <span className="meta-item">Updated {new Date(project.updated_at).toLocaleDateString()}</span>
            )}
            <span className="meta-item">by {project.created_by}</span>
          </div>
        </div>
        <button className="btn btn-primary" onClick={() => setShowForm(!showForm)}>
          {showForm ? 'Cancel' : '+ New Package'}
        </button>
      </div>

      {error && <div className="error-message">{error}</div>}

      {showForm && (
        <form className="form card" onSubmit={handleCreatePackage}>
          <h3>Create New Package</h3>
          <div className="form-row">
            <div className="form-group">
              <label htmlFor="name">Name</label>
              <input
                id="name"
                type="text"
                value={newPackage.name}
                onChange={(e) => setNewPackage({ ...newPackage, name: e.target.value })}
                placeholder="releases"
                required
              />
            </div>
            <div className="form-group">
              <label htmlFor="format">Format</label>
              <select
                id="format"
                value={newPackage.format}
                onChange={(e) => setNewPackage({ ...newPackage, format: e.target.value })}
              >
                {FORMAT_OPTIONS.map((f) => (
                  <option key={f} value={f}>
                    {f}
                  </option>
                ))}
              </select>
            </div>
          </div>
          <div className="form-group">
            <label htmlFor="description">Description</label>
            <input
              id="description"
              type="text"
              value={newPackage.description}
              onChange={(e) => setNewPackage({ ...newPackage, description: e.target.value })}
              placeholder="Optional description"
            />
          </div>
          <button type="submit" className="btn btn-primary" disabled={creating}>
            {creating ? 'Creating...' : 'Create Package'}
          </button>
        </form>
      )}

      <div className="list-controls">
        <SearchInput
          value={search}
          onChange={handleSearchChange}
          placeholder="Filter packages..."
          className="list-controls__search"
        />
        <select
          className="list-controls__select"
          value={format}
          onChange={(e) => handleFormatChange(e.target.value)}
        >
          <option value="">All formats</option>
          {FORMAT_OPTIONS.map((f) => (
            <option key={f} value={f}>
              {f}
            </option>
          ))}
        </select>
        <SortDropdown options={SORT_OPTIONS} value={sort} order={order} onChange={handleSortChange} />
      </div>

      {hasActiveFilters && (
        <FilterChipGroup onClearAll={clearFilters}>
          {search && <FilterChip label="Filter" value={search} onRemove={() => handleSearchChange('')} />}
          {format && <FilterChip label="Format" value={format} onRemove={() => handleFormatChange('')} />}
        </FilterChipGroup>
      )}

      {packages.length === 0 ? (
        <div className="empty-state">
          {hasActiveFilters ? (
            <p>No packages match your filters. Try adjusting your search.</p>
          ) : (
            <p>No packages yet. Create your first package to start uploading artifacts!</p>
          )}
        </div>
      ) : (
        <>
          <div className="project-grid">
            {packages.map((pkg) => (
              <Link to={`/project/${projectName}/${pkg.name}`} key={pkg.id} className="project-card card">
                <div className="package-card__header">
                  <h3>{pkg.name}</h3>
                  <Badge variant="default">{pkg.format}</Badge>
                </div>
                {pkg.description && <p>{pkg.description}</p>}

                {(pkg.tag_count !== undefined || pkg.artifact_count !== undefined) && (
                  <div className="package-stats">
                    {pkg.tag_count !== undefined && (
                      <div className="package-stats__item">
                        <span className="package-stats__value">{pkg.tag_count}</span>
                        <span className="package-stats__label">Tags</span>
                      </div>
                    )}
                    {pkg.artifact_count !== undefined && (
                      <div className="package-stats__item">
                        <span className="package-stats__value">{pkg.artifact_count}</span>
                        <span className="package-stats__label">Artifacts</span>
                      </div>
                    )}
                    {pkg.total_size !== undefined && pkg.total_size > 0 && (
                      <div className="package-stats__item">
                        <span className="package-stats__value">{formatBytes(pkg.total_size)}</span>
                        <span className="package-stats__label">Size</span>
                      </div>
                    )}
                  </div>
                )}

                <div className="project-meta">
                  {pkg.latest_tag && (
                    <span className="latest-tag">
                      Latest: <strong>{pkg.latest_tag}</strong>
                    </span>
                  )}
                  <span className="date">Created {new Date(pkg.created_at).toLocaleDateString()}</span>
                </div>
              </Link>
            ))}
          </div>

          {pagination && pagination.total_pages > 1 && (
            <Pagination
              page={pagination.page}
              totalPages={pagination.total_pages}
              total={pagination.total}
              limit={pagination.limit}
              onPageChange={handlePageChange}
            />
          )}
        </>
      )}
    </div>
  );
}

export default ProjectPage;
