
"use client";

import React, { useState, useEffect } from 'react';
import { useAuth } from '@/contexts/AuthContext';
import { useRouter } from 'next/navigation';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Textarea } from '@/components/ui/textarea';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useToast } from '@/hooks/use-toast';
import { Loader2, ShieldAlert, Save, UploadCloud, Info, Search as SearchIcon, ListFilter } from 'lucide-react';
import { saveTescoStoreDirectory, searchTescoDirectory, type SaveDirectoryOutput, type SearchDirectoryInput, type SearchDirectoryOutput } from '@/ai/flows/tescoStoreDirectoryFlow';
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { TableHeader, TableRow, TableHead, TableCell, TableBody } from "@/components/ui/table";
import { ScrollArea } from '@/components/ui/scroll-area';
import { Separator } from '@/components/ui/separator';

// Headers to display in the search results table, in the desired order.
const DISPLAY_HEADERS = [
  "Store Number",
  "Store Name",
  "Associated PFS",
  "Associated UFC",
  "Store Street Address",
  "Store Postcode",
  "Pre Count Contact Type",
  "Direct Dial (Duty Manager)",
  "Direct Dial (Cust Serv Desk)",
  "Store Manager",
  "Store Manager Email",
  "Simpler Variance Category"
];

// Helper to sanitize header names for SQL-like data keys
// This must match the sanitization in tescoStoreDirectoryFlow.ts
function sanitizeHeaderForDataKey(header: string): string {
  return header.replace(/[^a-zA-Z0-9_]/g, '_').replace(/^[^a-zA-Z_]+|[^a-zA-Z0-9_]+$/g, '');
}


export default function StoreDirectoryPage() {
  const { user, isLoading: isAuthLoading, isAuthenticated } = useAuth();
  const router = useRouter();
  const { toast } = useToast();

  // State for uploading
  const [pastedData, setPastedData] = useState('');
  const [isSaving, setIsSaving] = useState(false);
  const [lastSaveResult, setLastSaveResult] = useState<SaveDirectoryOutput | null>(null);

  // State for searching
  const [searchStoreNumber, setSearchStoreNumber] = useState('');
  const [searchStoreName, setSearchStoreName] = useState('');
  const [searchPostcode, setSearchPostcode] = useState('');
  const [isSearching, setIsSearching] = useState(false);
  const [searchResults, setSearchResults] = useState<Array<Record<string, any>> | null>(null);
  const [searchPerformed, setSearchPerformed] = useState(false);


  const handleSaveDirectory = async () => {
    if (!pastedData.trim()) {
      toast({
        title: "No Data Provided",
        description: "Please paste data into the text area.",
        variant: "destructive",
      });
      return;
    }
    setIsSaving(true);
    setLastSaveResult(null);
    try {
      const result = await saveTescoStoreDirectory({ pastedData });
      setLastSaveResult(result);

      if (result.success) {
        toast({
          title: "Directory Data Processed",
          description: result.message || `Successfully processed ${result.itemCount || 0} records.`,
        });
        const now = new Date().toISOString();
        localStorage.setItem('tescoStoreDirectoryLastUpdated', now);
        window.dispatchEvent(new StorageEvent('storage', {
            key: 'tescoStoreDirectoryLastUpdated',
            newValue: now
        }));

      } else {
        toast({
          title: "Error Processing Directory",
          description: result.message || "An unknown error occurred.",
          variant: "destructive",
        });
      }
    } catch (error: any) {
      console.error("Error calling saveTescoStoreDirectory flow:", error);
      toast({
        title: "Flow Execution Error",
        description: error.message || "Failed to execute the save directory flow.",
        variant: "destructive",
      });
      setLastSaveResult({ success: false, message: error.message || "Flow execution failed." });
    } finally {
      setIsSaving(false);
    }
  };

  const handleSearchDirectory = async () => {
    if (!searchStoreNumber && !searchStoreName && !searchPostcode) {
      toast({
        title: "No Search Terms",
        description: "Please enter at least one search term (Store No, Name, or Postcode).",
        variant: "default"
      });
      return;
    }
    setIsSearching(true);
    setSearchResults(null);
    setSearchPerformed(true);
    try {
      const input: SearchDirectoryInput = {};
      if (searchStoreNumber) input.storeNumber = searchStoreNumber;
      if (searchStoreName) input.storeName = searchStoreName;
      if (searchPostcode) input.postcode = searchPostcode;

      const result = await searchTescoDirectory(input);
      if (result.success && result.results) {
        setSearchResults(result.results);
        toast({
          title: "Search Complete",
          description: result.message || `Found ${result.itemCount || 0} stores.`,
        });
      } else {
        setSearchResults([]);
        toast({
          title: "Search Information",
          description: result.message || "No matching stores found or search failed.",
          variant: result.success ? "default" : "destructive",
        });
      }
    } catch (error: any) {
      console.error("Error calling searchTescoDirectory flow:", error);
      setSearchResults([]);
      toast({
        title: "Search Flow Error",
        description: error.message || "Failed to execute the search directory flow.",
        variant: "destructive",
      });
    } finally {
      setIsSearching(false);
    }
  };


  if (isAuthLoading) {
    return (
      <div className="container mx-auto p-4 sm:p-6 lg:p-8 flex flex-col items-center justify-center min-h-[calc(100vh-150px)]">
        <Loader2 className="h-12 w-12 text-primary animate-spin mb-4" />
        <p className="text-muted-foreground">Loading page...</p>
      </div>
    );
  }

  if (!isAuthenticated || user?.role !== 'admin') {
    if (typeof window !== 'undefined') {
      router.push('/auth/denied?reason=admin_only');
    }
    return (
      <div className="container mx-auto p-4 sm:p-6 lg:p-8 flex flex-col items-center justify-center min-h-[calc(100vh-150px)]">
        <ShieldAlert className="h-12 w-12 text-destructive animate-pulse mb-4" />
        <p className="text-muted-foreground">Access Denied. Redirecting...</p>
      </div>
    );
  }

  return (
    <div className="container mx-auto px-4 py-12 flex flex-col items-center min-h-[calc(100vh-150px)] space-y-8">
      {/* Upload Section */}
      <Card className="w-full max-w-2xl shadow-xl">
        <CardHeader>
          <CardTitle className="text-2xl font-bold text-primary flex items-center gap-2">
            <UploadCloud className="h-7 w-7" /> Tesco Store Directory Upload
          </CardTitle>
          <CardDescription>
            Paste the complete store directory data from Excel (first line should be headers).
            Each new submission will overwrite the existing directory data in the <code className="font-mono text-xs bg-muted px-1 py-0.5 rounded">tesco_master_data.db</code> SQLite database.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-6">
          <div>
            <Textarea
              value={pastedData}
              onChange={(e) => setPastedData(e.target.value)}
              placeholder="Paste tab-separated store directory data here..."
              rows={10}
              className="bg-background text-sm"
              disabled={isSaving}
            />
          </div>
          <Button onClick={handleSaveDirectory} disabled={isSaving || !pastedData.trim()} className="w-full">
            {isSaving ? (
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
            ) : (
              <Save className="mr-2 h-4 w-4" />
            )}
            Process and Save Directory
          </Button>

          {lastSaveResult && (
            <Alert variant={lastSaveResult.success ? "default" : "destructive"} className="mt-4">
              <Info className="h-4 w-4" />
              <AlertTitle>{lastSaveResult.success ? "Processing Result" : "Processing Error"}</AlertTitle>
              <AlertDescription>
                {lastSaveResult.message}
                {lastSaveResult.success && lastSaveResult.headers && (
                  <div className="mt-2">
                    <p className="font-semibold">Detected Headers ({lastSaveResult.headers.length}):</p>
                    <p className="text-xs break-all">{lastSaveResult.headers.join(', ')}</p>
                  </div>
                )}
                {lastSaveResult.success && lastSaveResult.parsedRecordsSample && lastSaveResult.parsedRecordsSample.length > 0 && (
                  <div className="mt-2">
                    <p className="font-semibold">Sample of Parsed Records (first {lastSaveResult.parsedRecordsSample.length}):</p>
                    <ScrollArea className="max-h-40">
                      <pre className="text-xs bg-muted p-2 rounded-md overflow-x-auto">
                        {JSON.stringify(lastSaveResult.parsedRecordsSample, null, 2)}
                      </pre>
                    </ScrollArea>
                  </div>
                )}
              </AlertDescription>
            </Alert>
          )}
        </CardContent>
      </Card>

      <Separator className="my-8" />

      {/* Search Section */}
      <Card className="w-full max-w-3xl shadow-xl">
        <CardHeader>
          <CardTitle className="text-2xl font-bold text-primary flex items-center gap-2">
            <SearchIcon className="h-7 w-7" /> Search Store Directory
          </CardTitle>
          <CardDescription>
            Search the uploaded store directory. Fields are optional; uses partial matching.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-6">
           <Alert variant="default" className="bg-primary/10 border-primary/30">
            <ListFilter className="h-4 w-4 text-primary" />
            <AlertTitle className="text-primary font-semibold">Search Tip</AlertTitle>
            <AlertDescription className="text-primary/80">
              For search to work correctly, ensure your uploaded directory includes headers such as:
              <code className="font-mono text-xs bg-muted px-1 py-0.5 rounded">'Store Number'</code>,
              <code className="font-mono text-xs bg-muted px-1 py-0.5 rounded">'Store Name'</code>, and/or
              <code className="font-mono text-xs bg-muted px-1 py-0.5 rounded">'Postcode'</code>.
              The system will sanitize these (e.g., 'Store Number' becomes 'Store_Number') for database querying.
            </AlertDescription>
          </Alert>
          <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
            <div>
              <Label htmlFor="searchStoreNumber">Store Number</Label>
              <Input
                id="searchStoreNumber"
                value={searchStoreNumber}
                onChange={(e) => setSearchStoreNumber(e.target.value)}
                placeholder="e.g., 1234"
                className="bg-background"
                disabled={isSearching}
              />
            </div>
            <div>
              <Label htmlFor="searchStoreName">Store Name</Label>
              <Input
                id="searchStoreName"
                value={searchStoreName}
                onChange={(e) => setSearchStoreName(e.target.value)}
                placeholder="e.g., Tesco Extra"
                className="bg-background"
                disabled={isSearching}
              />
            </div>
            <div>
              <Label htmlFor="searchPostcode">Postcode</Label>
              <Input
                id="searchPostcode"
                value={searchPostcode}
                onChange={(e) => setSearchPostcode(e.target.value)}
                placeholder="e.g., AB1 2CD"
                className="bg-background"
                disabled={isSearching}
              />
            </div>
          </div>
          <Button onClick={handleSearchDirectory} disabled={isSearching} className="w-full">
            {isSearching ? (
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
            ) : (
              <SearchIcon className="mr-2 h-4 w-4" />
            )}
            Search Directory
          </Button>
        </CardContent>
      </Card>

      {/* Search Results Section */}
      {searchPerformed && (
        <Card className="w-full max-w-6xl shadow-xl mt-8">
          <CardHeader>
            <CardTitle className="text-xl text-primary">Search Results</CardTitle>
            <CardDescription>
              {searchResults ? `${searchResults.length} store(s) found.` : 'No results or error during search.'}
            </CardDescription>
          </CardHeader>
          <CardContent>
            {isSearching ? (
              <div className="flex justify-center items-center p-8">
                <Loader2 className="h-8 w-8 text-primary animate-spin" />
                <p className="ml-3 text-muted-foreground">Searching...</p>
              </div>
            ) : searchResults && searchResults.length > 0 ? (
                <div className="max-h-[600px] overflow-y-auto rounded-md border"> {/* Vertical scroll container */}
                    <div className="overflow-x-auto"> {/* Horizontal scroll container */}
                        <table className="min-w-full text-xs"> {/* Table itself */}
                        <TableHeader className="bg-muted/50 z-10">
                            <TableRow>
                            {DISPLAY_HEADERS.map((header) => (
                                <TableHead key={header} className="whitespace-nowrap px-3 py-2">{header}</TableHead>
                            ))}
                            </TableRow>
                        </TableHeader>
                        <TableBody>
                            {searchResults.map((row, rowIndex) => (
                            <TableRow key={rowIndex}>
                                {DISPLAY_HEADERS.map((header) => {
                                const dataKey = sanitizeHeaderForDataKey(header);
                                return (
                                    <TableCell key={`${rowIndex}-${header}`} className="whitespace-nowrap px-3 py-2">
                                    {String(row[dataKey] ?? '')}
                                    </TableCell>
                                );
                                })}
                            </TableRow>
                            ))}
                        </TableBody>
                        </table>
                    </div>
                </div>
            ) : (
              <p className="text-center text-muted-foreground p-8">No matching stores found for your criteria.</p>
            )}
          </CardContent>
        </Card>
      )}
    </div>
  );
}
