'use client';

import { useState, useEffect, useRef } from 'react';
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Loader2, Check, ArrowUp, ArrowDown } from 'lucide-react';
import {
  projectService,
  packageService,
  chainageService,
} from '@/services/api';
import {
  Project,
  Package as PackageType,
  Chainage,
  SessionContext,
} from '@/types';
import { cn } from '@/lib/utils';

type ProjectSelectionSectionProps = {
  onSelectionComplete?: (session: SessionContext) => void;
  onSelectionChange?: (session: SessionContext | null) => void;
  asStep?: boolean;
  hideButton?: boolean;
};

let globalProjectsCache: Project[] | null = null;
let projectsPromise: Promise<Project[]> | null = null;

export function ProjectSelectionSection({
  onSelectionComplete,
  onSelectionChange,
  asStep = false,
  hideButton = false,
}: ProjectSelectionSectionProps) {
  // Data states
  const [projects, setProjects] = useState<Project[]>(
    globalProjectsCache || [],
  );
  const [packages, setPackages] = useState<PackageType[]>([]);
  const [chainages, setChainages] = useState<Chainage[]>([]);

  // Selection states
  const [selectedProject, setSelectedProject] = useState<Project | null>(null);
  const [selectedPackage, setSelectedPackage] = useState<PackageType | null>(
    null,
  );
  const [selectedChainage, setSelectedChainage] = useState<Chainage | null>(
    null,
  );

  // Loading states
  const [loadingProjects, setLoadingProjects] = useState(!globalProjectsCache);
  const [loadingPackages, setLoadingPackages] = useState(false);
  const [loadingChainages, setLoadingChainages] = useState(false);

  // Error state
  const [error, setError] = useState<string | null>(null);

  // Load projects on mount
  useEffect(() => {
    let isMounted = true;

    const loadProjects = async () => {
      // Use cache if we already have it
      if (globalProjectsCache) {
        if (isMounted) {
          setProjects(globalProjectsCache);
          setLoadingProjects(false);
        }
        return;
      }

      // If a fetch is already in flight, reuse that promise
      if (!projectsPromise) {
        projectsPromise = projectService
          .getProjects()
          .then((data) => {
            globalProjectsCache = data.items;
            return data.items;
          })
          .catch((err) => {
            projectsPromise = null; // Reset on error to allow retry
            throw err;
          });
      }

      try {
        setLoadingProjects(true);
        const data = await projectsPromise;
        if (isMounted) {
          setProjects(data);
        }
      } catch (err) {
        if (isMounted) {
          setError('Failed to load projects. Please check connection.');
        }
      } finally {
        if (isMounted) {
          setLoadingProjects(false);
        }
      }
    };

    loadProjects();
    return () => {
      isMounted = false;
    };
  }, []);

  // Load packages when project changes
  useEffect(() => {
    if (!selectedProject) {
      setPackages([]);
      setSelectedPackage(null);
      return;
    }

    let isMounted = true;
    const loadPackages = async () => {
      try {
        setLoadingPackages(true);
        setError(null);
        setSelectedPackage(null);
        setSelectedChainage(null);
        setChainages([]);
        const data = await packageService.getPackagesByProject(
          selectedProject.id,
        );
        if (isMounted) {
          setPackages(data.items);
        }
      } catch (err) {
        if (isMounted) {
          console.error('Failed to load packages:', err);
          setError('Failed to load packages for the selected project.');
        }
      } finally {
        if (isMounted) {
          setLoadingPackages(false);
        }
      }
    };
    loadPackages();
    return () => {
      isMounted = false;
    };
  }, [selectedProject]);

  // Load chainages when package changes
  useEffect(() => {
    if (!selectedPackage) {
      setChainages([]);
      setSelectedChainage(null);
      return;
    }

    let isMounted = true;
    const loadChainages = async () => {
      try {
        setLoadingChainages(true);
        setError(null);
        setSelectedChainage(null);
        const data = await chainageService.getChainagesByPackage(
          selectedPackage.id,
        );
        if (isMounted) {
          setChainages(data.items);
        }
      } catch (err) {
        if (isMounted) {
          console.error('Failed to load chainages:', err);
          setError('Failed to load segments for the selected package.');
        }
      } finally {
        if (isMounted) {
          setLoadingChainages(false);
        }
      }
    };
    loadChainages();
    return () => {
      isMounted = false;
    };
  }, [selectedPackage]);

  const handleProjectChange = (projectId: string) => {
    const project = projects.find((p) => p.id === projectId) || null;
    setSelectedProject(project);
  };

  const handlePackageChange = (packageId: string) => {
    const pkg = packages.find((p) => p.id === packageId) || null;
    setSelectedPackage(pkg);
  };

  const handleChainageChange = (chainageId: string) => {
    const chainage = chainages.find((chn) => chn.id === chainageId) || null;
    setSelectedChainage(chainage);
  };

  // Cache the last reported state to prevent infinite loops
  const lastReportedIdRef = useRef<string | null>(null);

  // Handle change reporting
  useEffect(() => {
    if (onSelectionChange) {
      const currentIds =
        selectedProject && selectedPackage && selectedChainage
          ? `${selectedProject.id}-${selectedPackage.id}-${selectedChainage.id}`
          : null;

      if (currentIds !== lastReportedIdRef.current) {
        lastReportedIdRef.current = currentIds;

        if (selectedProject && selectedPackage && selectedChainage) {
          onSelectionChange({
            projectId: selectedProject.id,
            projectName: selectedProject.name,
            packageId: selectedPackage.id,
            packageName: selectedPackage.name,
            chainageId: selectedChainage.id,
            chainageName: selectedChainage.segment_name,
            chainageDirection: selectedChainage.direction,
          });
        } else {
          onSelectionChange(null);
        }
      }
    }
  }, [selectedProject, selectedPackage, selectedChainage, onSelectionChange]);

  const handleProceed = () => {
    if (
      selectedProject &&
      selectedPackage &&
      selectedChainage &&
      onSelectionComplete
    ) {
      onSelectionComplete({
        projectId: selectedProject.id,
        projectName: selectedProject.name,
        packageId: selectedPackage.id,
        packageName: selectedPackage.name,
        chainageId: selectedChainage.id,
        chainageName: selectedChainage.segment_name,
        chainageDirection: selectedChainage.direction,
      });
    }
  };

  const isComplete = selectedProject && selectedPackage && selectedChainage;

  // Step status helpers
  const getStepStatus = (step: number) => {
    if (step === 1) return selectedProject ? 'completed' : 'active';
    if (step === 2)
      return selectedPackage
        ? 'completed'
        : selectedProject
          ? 'active'
          : 'pending';
    if (step === 3)
      return selectedChainage
        ? 'completed'
        : selectedPackage
          ? 'active'
          : 'pending';
    return 'pending';
  };

  const content = (
    <>
      {/* Error Display */}
      {error && (
        <div className="p-4 rounded-md bg-destructive/10 border border-destructive/20 text-destructive text-sm mb-6">
          {error}
        </div>
      )}

      <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
        {/* Project Dropdown */}
        <div className="space-y-2">
          <Label htmlFor="project" className="text-sm font-semibold">
            Project
          </Label>
          <Select
            value={selectedProject?.id || ''}
            onValueChange={handleProjectChange}
            disabled={loadingProjects}
          >
            <SelectTrigger id="project" className="h-11">
              {loadingProjects ? (
                <div className="flex items-center gap-2">
                  <Loader2 className="h-4 w-4 animate-spin" />
                  <span>Loading...</span>
                </div>
              ) : (
                <SelectValue placeholder="Select project" />
              )}
            </SelectTrigger>
            <SelectContent>
              {projects.map((project) => (
                <SelectItem key={project.id} value={project.id}>
                  {project.name}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        {/* Package Dropdown */}
        <div className="space-y-2">
          <Label htmlFor="package" className="text-sm font-semibold">
            Package
          </Label>
          <Select
            value={selectedPackage?.id || ''}
            onValueChange={handlePackageChange}
            disabled={!selectedProject || loadingPackages}
          >
            <SelectTrigger id="package" className="h-11">
              {loadingPackages ? (
                <div className="flex items-center gap-2">
                  <Loader2 className="h-4 w-4 animate-spin" />
                  <span>Loading...</span>
                </div>
              ) : (
                <SelectValue
                  placeholder={
                    selectedProject ? 'Select package' : 'Select project first'
                  }
                />
              )}
            </SelectTrigger>
            <SelectContent>
              {packages.map((pkg) => (
                <SelectItem key={pkg.id} value={pkg.id}>
                  {pkg.name}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        {/* Chainage Dropdown */}
        <div className="space-y-2">
          <Label htmlFor="chainage" className="text-sm font-semibold">
            Segment
          </Label>
          <Select
            value={selectedChainage?.id || ''}
            onValueChange={handleChainageChange}
            disabled={!selectedPackage || loadingChainages}
          >
            <SelectTrigger id="chainage" className="h-11">
              {loadingChainages ? (
                <div className="flex items-center gap-2">
                  <Loader2 className="h-4 w-4 animate-spin" />
                  <span>Loading...</span>
                </div>
              ) : (
                <SelectValue
                  placeholder={
                    selectedPackage ? 'Select segment' : 'Select package first'
                  }
                />
              )}
            </SelectTrigger>
            <SelectContent>
              {chainages.map((chn) => (
                <SelectItem key={chn.id} value={chn.id}>
                  <div className="flex flex-col gap-0.5 py-0.5">
                    <span className="font-semibold text-sm">
                      {chn.segment_name}
                    </span>
                    <div className="flex items-center gap-2 text-[10px] text-muted-foreground font-medium">
                      <span>
                        {chn.chainage_start_km}-{chn.chainage_end_km} km
                      </span>
                      <span className="h-2.5 w-px bg-border" />
                      <span className="flex items-center gap-1 uppercase">
                        {chn.direction === 'UP' ? (
                          <ArrowUp className="h-2.5 w-2.5" />
                        ) : (
                          <ArrowDown className="h-2.5 w-2.5" />
                        )}
                        {chn.direction}
                      </span>
                    </div>
                  </div>
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      </div>

      {/* Selected Summary - Only if not asStep or if specifically desired */}
      {!asStep && isComplete && (
        <div className="px-4 py-3 rounded-md bg-secondary/50 border text-sm mb-8">
          <div className="flex items-center gap-2 flex-wrap text-muted-foreground">
            <span className="font-semibold text-foreground">Selection:</span>
            <span className="text-foreground">{selectedProject?.name}</span>
            <span>/</span>
            <span className="text-foreground">{selectedPackage?.name}</span>
            <span>/</span>
            <span className="text-foreground flex items-center gap-1.5">
              {selectedChainage?.segment_name}
              <span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-muted text-[10px] font-bold uppercase border">
                {selectedChainage?.direction === 'UP' ? (
                  <ArrowUp className="h-2.5 w-2.5" />
                ) : (
                  <ArrowDown className="h-2.5 w-2.5" />
                )}
                {selectedChainage?.direction}
              </span>
            </span>
          </div>
        </div>
      )}

      {/* Proceed Button */}
      {!hideButton && (
        <Button
          onClick={handleProceed}
          disabled={!isComplete}
          className="w-full h-14 text-base font-bold uppercase tracking-wider"
          size="lg"
        >
          {isComplete ? 'Proceed to Upload' : 'Select all fields to proceed'}
        </Button>
      )}
    </>
  );

  if (asStep) {
    return content;
  }

  return (
    <Card className="overflow-hidden">
      <CardHeader className="pb-6">
        <div className="flex flex-col gap-6">
          <div>
            <CardTitle className="text-2xl font-bold">
              Select Project Segment
            </CardTitle>
            <CardDescription className="mt-2 text-base">
              Select Project, Package & Segment to begin intelligent road
              analysis.
            </CardDescription>
          </div>

          {/* Step Progress Indicator */}
          <div className="flex items-center justify-center pt-2">
            {[1, 2, 3].map((step, index) => {
              const status = getStepStatus(step);
              const labels = ['Project', 'Package', 'Segment'];
              return (
                <div key={step} className="flex items-center">
                  <div className="flex flex-col items-center">
                    <div
                      className={cn(
                        'w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold transition-all',
                        status === 'completed'
                          ? 'bg-primary text-primary-foreground'
                          : status === 'active'
                            ? 'bg-primary text-primary-foreground ring-4 ring-primary/10'
                            : 'bg-muted text-muted-foreground',
                      )}
                    >
                      {status === 'completed' ? (
                        <Check className="h-5 w-5" />
                      ) : (
                        step
                      )}
                    </div>
                    <span
                      className={cn(
                        'text-xs mt-2 font-medium',
                        status === 'pending'
                          ? 'text-muted-foreground/60'
                          : 'text-foreground',
                      )}
                    >
                      {labels[index]}
                    </span>
                  </div>
                  {index < 2 && (
                    <div
                      className={cn(
                        'w-16 h-0.5 mx-2 mb-6 rounded-full',
                        getStepStatus(step + 1) !== 'pending'
                          ? 'bg-primary'
                          : 'bg-border',
                      )}
                    />
                  )}
                </div>
              );
            })}
          </div>
        </div>
      </CardHeader>

      <CardContent className="pt-0">{content}</CardContent>
    </Card>
  );
}
