'use client';

import { useEffect, useState } from 'react';
import { registryApi, instanceApi, clusterApi, valuesTemplateApi, storageApi } from '@/lib/api';
import { Package, Database, ChevronRight, Search, Rocket, X, Loader2 } from 'lucide-react';

interface RegistryDTO {
  id: string;
  name: string;
  url: string;
  description?: string;
  username?: string;
  insecure: boolean;
  isShared: boolean;
  createdAt: string;
  updatedAt: string;
}

interface CreateInstanceRequest {
  name: string;
  namespace: string;
  registryId: string;
  repository: string;
  chart: string;
  version: string;
  description?: string;
  valuesYaml?: string;
}

interface ClusterDTO {
  id: string;
  name: string;
  host: string;
  description?: string;
}

interface ValuesTemplateDTO {
  id: string;
  name: string;
  description?: string;
  values_yaml: string;
  version: number;
  is_default: boolean;
  chart_reference_id: string;
}

interface StorageDTO {
  id: string;
  name: string;
  type: string;
  description?: string;
}

export default function ChartsPage() {
  const [registries, setRegistries] = useState<RegistryDTO[]>([]);
  const [clusters, setClusters] = useState<ClusterDTO[]>([]);
  const [templates, setTemplates] = useState<ValuesTemplateDTO[]>([]);
  const [storages, setStorages] = useState<StorageDTO[]>([]);
  const [selectedRegistry, setSelectedRegistry] = useState<RegistryDTO | null>(null);
  const [repositories, setRepositories] = useState<string[]>([]);
  const [selectedRepo, setSelectedRepo] = useState<string | null>(null);
  const [artifacts, setArtifacts] = useState<Artifact[]>([]);
  const [searchQuery, setSearchQuery] = useState('');
  const [isLoading, setIsLoading] = useState(true);
  const [isLoadingRepos, setIsLoadingRepos] = useState(false);
  const [isLoadingArtifacts, setIsLoadingArtifacts] = useState(false);
  const [showDeployModal, setShowDeployModal] = useState(false);
  const [selectedArtifact, setSelectedArtifact] = useState<Artifact | null>(null);
  const [isDeploying, setIsDeploying] = useState(false);
  const [deployError, setDeployError] = useState<string | null>(null);
  const [valuesYamlError, setValuesYamlError] = useState<string | null>(null);
  const [deployForm, setDeployForm] = useState({
    name: '',
    namespace: 'default',
    clusterId: '',
    description: '',
    valuesYaml: '',
    selectedTemplateId: '',
    selectedStorageId: '',
  });

  const fetchRegistries = async () => {
    try {
      const response = await registryApi.list();
      const data = response.data;
      setRegistries(Array.isArray(data) ? data : (data?.registries || []));
    } catch (error) {
      console.error('Failed to fetch registries:', error);
    } finally {
      setIsLoading(false);
    }
  };

  const fetchClusters = async () => {
    try {
      const response = await clusterApi.list();
      const data = response.data;
      const clusterList = Array.isArray(data) ? data : (data?.clusters || []);
      setClusters(clusterList);
      if (clusterList.length > 0 && !deployForm.clusterId) {
        setDeployForm(prev => ({ ...prev, clusterId: clusterList[0].id }));
      }
    } catch (error) {
      console.error('Failed to fetch clusters:', error);
    }
  };

  const fetchTemplates = async () => {
    try {
      const response = await valuesTemplateApi.list();
      const data = response.data;
      const templateList = Array.isArray(data) ? data : (data?.templates || []);
      setTemplates(templateList);
    } catch (error) {
      console.error('Failed to fetch templates:', error);
    }
  };

  const fetchStorages = async () => {
    try {
      const response = await storageApi.list();
      const data = response.data;
      const storageList = Array.isArray(data) ? data : (data?.storages || []);
      setStorages(storageList);
    } catch (error) {
      console.error('Failed to fetch storages:', error);
    }
  };

  const handleTemplateChange = (templateId: string) => {
    const template = templates.find(t => t.id === templateId);
    if (template) {
      setDeployForm(prev => ({ ...prev, selectedTemplateId: templateId, valuesYaml: template.values_yaml }));
    }
  };

  const handleStorageChange = (storageId: string) => {
    const storage = storages.find(s => s.id === storageId);
    if (storage) {
      // Merge storage config into values using proper persistence format
      let storageConfig = '';
      if (storage.type === 'nfs') {
        // For NFS, use the storage name as storageClass reference
        storageConfig = `persistence:
  enabled: true
  storageClass: "${storage.name}"
  existingClaim: ""
  mountOptions:
    - hard
    - nfsvers=4.1
`;
      } else {
        storageConfig = `persistence:
  enabled: true
  storageClass: "${storage.type}"
  existingClaim: ""
`;
      }
      setDeployForm(prev => ({
        ...prev,
        selectedStorageId: storageId,
        valuesYaml: prev.valuesYaml ? prev.valuesYaml + '\n' + storageConfig : storageConfig
      }));
    }
  };

  const fetchRepositories = async (registryId: string) => {
    setIsLoadingRepos(true);
    setRepositories([]);
    setSelectedRepo(null);
    try {
      const response = await registryApi.listRepositories(registryId);
      setRepositories(response.data?.repositories || []);
    } catch (error) {
      console.error('Failed to fetch repositories:', error);
    } finally {
      setIsLoadingRepos(false);
    }
  };

  const fetchArtifacts = async (registryId: string, repositoryName: string) => {
    setIsLoadingArtifacts(true);
    setArtifacts([]);
    try {
      const response = await registryApi.listArtifacts(registryId, repositoryName);
      // Filter to only show chart type artifacts
      const allArtifacts = Array.isArray(response.data) ? response.data : [];
      const chartArtifacts = allArtifacts.filter((a: Artifact) => a.type === 'chart');
      // Sort by semver descending so index 0 = latest (most recent version)
      chartArtifacts.sort((a, b) => {
        const pa = a.tag.split('.').map(Number);
        const pb = b.tag.split('.').map(Number);
        for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
          const na = pa[i] || 0;
          const nb = pb[i] || 0;
          if (na !== nb) return nb - na;
        }
        return 0;
      });
      setArtifacts(chartArtifacts);
    } catch (error) {
      console.error('Failed to fetch artifacts:', error);
    } finally {
      setIsLoadingArtifacts(false);
    }
  };

  useEffect(() => {
    fetchRegistries();
    fetchClusters();
    fetchTemplates();
    fetchStorages();
  }, []);

  useEffect(() => {
    if (selectedRegistry) {
      fetchRepositories(selectedRegistry.id);
    }
  }, [selectedRegistry]);

  useEffect(() => {
    if (selectedRegistry && selectedRepo) {
      fetchArtifacts(selectedRegistry.id, selectedRepo);
    }
  }, [selectedRepo]);

  const filteredRepos = repositories.filter(repo =>
    repo.toLowerCase().includes(searchQuery.toLowerCase())
  );

  // Only show chart repositories (those starting with "charts/")
  const chartRepos = filteredRepos.filter(repo => repo.startsWith('charts/') || repo.includes('/charts/'));

  const handleDeploy = async () => {
    if (!selectedArtifact || !deployForm.clusterId || !deployForm.name) {
      alert('Please fill in all required fields');
      return;
    }

    setIsDeploying(true);
    setDeployError(null);

    try {
      const request: CreateInstanceRequest = {
        name: deployForm.name,
        namespace: deployForm.namespace || 'default',
        repository: selectedRepo!,
        chart: selectedRepo!.split('/').pop() || selectedRepo!,
        version: selectedArtifact.tag,
        registryId: selectedRegistry?.id || '',
        description: deployForm.description,
        valuesYaml: deployForm.valuesYaml || undefined,
      };

      await instanceApi.create(deployForm.clusterId, request);
      alert('Deployment created successfully!');
      setShowDeployModal(false);
      setSelectedArtifact(null);
      setDeployForm({
        name: '',
        namespace: 'default',
        clusterId: clusters[0]?.id || '',
        description: '',
        valuesYaml: '',
        selectedTemplateId: '',
        selectedStorageId: '',
      });
    } catch (error: unknown) {
      console.error('Failed to deploy:', error);
      let errorMessage = 'Failed to create deployment';
      if (error && typeof error === 'object' && 'response' in error) {
        const axiosError = error as { response?: { data?: { error?: string; message?: string } } };
        errorMessage = axiosError.response?.data?.message || axiosError.response?.data?.error || errorMessage;
      }
      setDeployError(errorMessage);
    } finally {
      setIsDeploying(false);
    }
  };

  const openDeployModal = (artifact: Artifact) => {
    setSelectedArtifact(artifact);
    setDeployForm({
      name: artifact.repositoryName.split('/').pop()!.toLowerCase(),
      namespace: 'default',
      clusterId: clusters[0]?.id || '',
      description: '',
      valuesYaml: '',
      selectedTemplateId: '',
      selectedStorageId: '',
    });
    setShowDeployModal(true);
  };

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-64">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[var(--primary)]"></div>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div>
        <h1 className="text-2xl font-bold text-[var(--foreground)]">Helm Charts</h1>
        <p className="text-[var(--muted-foreground)]">Browse and deploy Helm charts from OCI registries</p>
      </div>

      {/* Registry Selection */}
      <div className="flex items-center gap-4">
        <label className="text-sm font-medium text-[var(--foreground)]">Registry:</label>
        <div className="flex gap-2 flex-wrap">
          {registries.map((registry) => (
            <button
              key={registry.id}
              onClick={() => {
                setSelectedRegistry(registry);
                setSelectedRepo(null);
              }}
              className={`flex items-center gap-2 px-4 py-2 rounded-lg border transition-all ${
                selectedRegistry?.id === registry.id
                  ? 'border-[var(--primary)] bg-[var(--primary)]/10 text-[var(--primary)]'
                  : 'border-[var(--border)] text-[var(--foreground)] hover:border-[var(--primary)]'
              }`}
            >
              <Database className="w-4 h-4" />
              {registry.name}
            </button>
          ))}
        </div>
      </div>

      {/* Search */}
      {selectedRegistry && (
        <div className="relative">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--muted-foreground)]" />
          <input
            type="text"
            placeholder="Search charts..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="w-full pl-10 pr-4 py-2 bg-[var(--card)] border border-[var(--border)] rounded-lg text-[var(--foreground)] placeholder:text-[var(--muted-foreground)]"
          />
        </div>
      )}

      {/* Breadcrumb */}
      {selectedRegistry && (
        <div className="flex items-center gap-2 text-sm">
          <button
            onClick={() => {
              setSelectedRegistry(null);
              setSelectedRepo(null);
            }}
            className="text-[var(--primary)] hover:underline"
          >
            Registries
          </button>
          <ChevronRight className="w-4 h-4 text-[var(--muted-foreground)]" />
          <span className="text-[var(--foreground)]">{selectedRegistry.name}</span>
          {selectedRepo && (
            <>
              <ChevronRight className="w-4 h-4 text-[var(--muted-foreground)]" />
              <span className="text-[var(--foreground)]">{selectedRepo}</span>
            </>
          )}
        </div>
      )}

      {/* Content */}
      {!selectedRegistry ? (
        <div className="card text-center py-12">
          <Package className="w-12 h-12 mx-auto text-[var(--muted-foreground)] mb-4" />
          <p className="text-[var(--muted-foreground)]">Select a registry to browse Helm charts</p>
        </div>
      ) : isLoadingRepos ? (
        <div className="flex items-center justify-center h-64">
          <Loader2 className="w-8 h-8 animate-spin text-[var(--primary)]" />
        </div>
      ) : !selectedRepo ? (
        /* Chart Repositories List */
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {chartRepos.length === 0 ? (
            <div className="col-span-full card text-center py-12">
              <Package className="w-12 h-12 mx-auto text-[var(--muted-foreground)] mb-4" />
              <p className="text-[var(--muted-foreground)]">
                {searchQuery ? 'No charts found matching your search' : 'No Helm charts found in this registry'}
              </p>
              {searchQuery && (
                <button
                  onClick={() => setSearchQuery('')}
                  className="mt-4 text-[var(--primary)] hover:underline"
                >
                  Clear search
                </button>
              )}
            </div>
          ) : (
            chartRepos.map((repo) => (
              <button
                key={repo}
                onClick={() => setSelectedRepo(repo)}
                className="card text-left hover:border-[var(--primary)] transition-all p-4"
              >
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-3">
                    <Package className="w-6 h-6 text-[var(--primary)]" />
                    <div>
                      <p className="font-semibold text-[var(--foreground)]">
                        {repo.split('/').pop()}
                      </p>
                      <p className="text-xs text-[var(--muted-foreground)]">{repo}</p>
                    </div>
                  </div>
                  <ChevronRight className="w-5 h-5 text-[var(--muted-foreground)]" />
                </div>
              </button>
            ))
          )}
        </div>
      ) : isLoadingArtifacts ? (
        <div className="flex items-center justify-center h-64">
          <Loader2 className="w-8 h-8 animate-spin text-[var(--primary)]" />
        </div>
      ) : (
        /* Artifact/Version List */
        <div className="space-y-4">
          <button
            onClick={() => setSelectedRepo(null)}
            className="flex items-center gap-2 text-sm text-[var(--primary)] hover:underline"
          >
            <ChevronRight className="w-4 h-4 rotate-180" />
            Back to charts
          </button>

          <h2 className="text-lg font-semibold text-[var(--foreground)]">
            Versions of {selectedRepo.split('/').pop()}
          </h2>

          {artifacts.length === 0 ? (
            <div className="card text-center py-12">
              <p className="text-[var(--muted-foreground)]">No versions found</p>
            </div>
          ) : (
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
              {artifacts.map((artifact, index) => (
                <div key={index} className="card">
                  <div className="flex items-start justify-between mb-3">
                    <div>
                      <p className="font-mono text-lg font-bold text-[var(--foreground)]">
                        {artifact.tag}
                      </p>
                      <p className="text-xs text-[var(--muted-foreground)]">
                        {artifact.mediaType}
                      </p>
                    </div>
                    {index === 0 && (
                      <span className="badge badge-success">Latest</span>
                    )}
                  </div>
                  <p className="text-xs text-[var(--muted-foreground)] mb-4">
                    Size: {formatSize(artifact.size)}
                  </p>
                  <button
                    onClick={() => openDeployModal(artifact)}
                    className="w-full flex items-center justify-center gap-2 px-4 py-2 bg-[var(--primary)] text-[var(--primary-foreground)] rounded-lg hover:opacity-90 transition-opacity"
                  >
                    <Rocket className="w-4 h-4" />
                    Deploy
                  </button>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {/* Deploy Modal */}
      {showDeployModal && selectedArtifact && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
          <div className="bg-[var(--card)] rounded-xl p-6 w-full max-w-lg border border-[var(--border)] max-h-[90vh] overflow-y-auto">
            <div className="flex items-center justify-between mb-4">
              <h2 className="text-xl font-bold text-[var(--foreground)]">Deploy Chart</h2>
              <button
                onClick={() => {
                  setShowDeployModal(false);
                  setDeployError(null);
                }}
                className="p-1 hover:bg-[var(--secondary)] rounded"
              >
                <X className="w-5 h-5 text-[var(--muted-foreground)]" />
              </button>
            </div>

            <div className="mb-4 p-3 bg-[var(--secondary)] rounded-lg">
              <p className="text-sm text-[var(--muted-foreground)]">Deploying</p>
              <p className="font-semibold text-[var(--foreground)]">
                {selectedRepo}:{selectedArtifact.tag}
              </p>
            </div>

            <div className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-[var(--foreground)] mb-1">
                  Release Name *
                </label>
                <input
                  type="text"
                  value={deployForm.name}
                  onChange={(e) => setDeployForm({ ...deployForm, name: e.target.value })}
                  className="w-full px-3 py-2 bg-[var(--background)] border border-[var(--border)] rounded-lg text-[var(--foreground)]"
                  placeholder="my-release"
                  required
                />
              </div>

              <div>
                <label className="block text-sm font-medium text-[var(--foreground)] mb-1">
                  Namespace
                </label>
                <input
                  type="text"
                  value={deployForm.namespace}
                  onChange={(e) => setDeployForm({ ...deployForm, namespace: e.target.value })}
                  className="w-full px-3 py-2 bg-[var(--background)] border border-[var(--border)] rounded-lg text-[var(--foreground)]"
                  placeholder="default"
                />
              </div>

              <div>
                <label className="block text-sm font-medium text-[var(--foreground)] mb-1">
                  Cluster *
                </label>
                <select
                  value={deployForm.clusterId}
                  onChange={(e) => setDeployForm({ ...deployForm, clusterId: e.target.value })}
                  className="w-full px-3 py-2 bg-[var(--background)] border border-[var(--border)] rounded-lg text-[var(--foreground)]"
                  required
                >
                  <option value="">Select a cluster</option>
                  {clusters.map((cluster) => (
                    <option key={cluster.id} value={cluster.id}>
                      {cluster.name} ({cluster.host})
                    </option>
                  ))}
                </select>
              </div>

              {templates.length > 0 && (
                <div>
                  <label className="block text-sm font-medium text-[var(--foreground)] mb-1">
                    Values Template
                  </label>
                  <select
                    value={deployForm.selectedTemplateId}
                    onChange={(e) => handleTemplateChange(e.target.value)}
                    className="w-full px-3 py-2 bg-[var(--background)] border border-[var(--border)] rounded-lg text-[var(--foreground)]"
                  >
                    <option value="">-- Select a template --</option>
                    {templates.map((template) => (
                      <option key={template.id} value={template.id}>
                        {template.name} (v{template.version}){template.is_default ? ' [Default]' : ''}
                      </option>
                    ))}
                  </select>
                </div>
              )}

              {storages.length > 0 && (
                <div>
                  <label className="block text-sm font-medium text-[var(--foreground)] mb-1">
                    Storage Backend
                  </label>
                  <select
                    value={deployForm.selectedStorageId}
                    onChange={(e) => handleStorageChange(e.target.value)}
                    className="w-full px-3 py-2 bg-[var(--background)] border border-[var(--border)] rounded-lg text-[var(--foreground)]"
                  >
                    <option value="">-- Select storage (optional) --</option>
                    {storages.map((storage) => (
                      <option key={storage.id} value={storage.id}>
                        {storage.name} ({storage.type})
                      </option>
                    ))}
                  </select>
                </div>
              )}

              <div>
                <label className="block text-sm font-medium text-[var(--foreground)] mb-1">
                  Description
                </label>
                <textarea
                  value={deployForm.description}
                  onChange={(e) => setDeployForm({ ...deployForm, description: e.target.value })}
                  className="w-full px-3 py-2 bg-[var(--background)] border border-[var(--border)] rounded-lg text-[var(--foreground)]"
                  rows={2}
                  placeholder="Optional description..."
                />
              </div>

              <div>
                <label className="block text-sm font-medium text-[var(--foreground)] mb-1">
                  Custom Values (values.yaml)
                </label>
                <textarea
                  value={deployForm.valuesYaml}
                  onChange={(e) => {
                    const val = e.target.value;
                    setDeployForm({ ...deployForm, valuesYaml: val });
                    // Client-side YAML syntax validation
                    if (val.trim()) {
                      try {
                        // Quick line-by-line check for common mistakes
                        const lines = val.split('\n');
                        for (const line of lines) {
                          const trimmed = line.trim();
                          if (trimmed && !trimmed.startsWith('#') && trimmed.includes('=') && !trimmed.includes(':')) {
                            const key = trimmed.split('=')[0].trim();
                            if (key && /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
                              setValuesYamlError(`Syntax error: use ":" instead of "=" for key "${key}" (YAML uses colons, not equals signs)`);
                              return;
                            }
                          }
                        }
                        setValuesYamlError(null);
                      } catch {}
                    } else {
                      setValuesYamlError(null);
                    }
                  }}
                  className={`w-full px-3 py-2 bg-[var(--background)] border rounded-lg text-[var(--foreground)] font-mono text-sm ${valuesYamlError ? 'border-red-500' : 'border-[var(--border)]'}`}
                  rows={4}
                  placeholder="# Optional: Override chart values&#10;replicaCount: 2&#10;image:&#11;  tag: latest"
                />
              </div>

              {valuesYamlError && (
                <div className="p-3 bg-red-500/10 border border-red-500/20 rounded-lg text-red-500 text-sm">
                  {valuesYamlError}
                </div>
              )}

              {deployError && (
                <div className="p-3 bg-red-500/10 border border-red-500/20 rounded-lg text-red-500 text-sm">
                  {deployError}
                </div>
              )}

              <div className="flex gap-3 pt-2">
                <button
                  type="button"
                  onClick={() => {
                    setShowDeployModal(false);
                    setDeployError(null);
                  }}
                  className="flex-1 px-4 py-2 border border-[var(--border)] text-[var(--foreground)] rounded-lg hover:bg-[var(--secondary)] transition-colors"
                >
                  Cancel
                </button>
                <button
                  type="button"
                  onClick={handleDeploy}
                  disabled={isDeploying || !deployForm.name || !deployForm.clusterId || !!valuesYamlError}
                  className="flex-1 px-4 py-2 bg-[var(--primary)] text-[var(--primary-foreground)] rounded-lg hover:opacity-90 transition-opacity disabled:opacity-50 flex items-center justify-center gap-2"
                >
                  {isDeploying && <Loader2 className="w-4 h-4 animate-spin" />}
                  {isDeploying ? 'Deploying...' : 'Deploy'}
                </button>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

interface Artifact {
  repositoryName: string;
  tag: string;
  type: string;
  mediaType: string;
  size: number;
}

function formatSize(bytes: number): string {
  if (bytes < 1024) return bytes + ' B';
  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
  return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
}