'use client';

import * as React from 'react';
import { Download, Loader2, Code2, Globe, Layout } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Progress } from '@/components/ui/progress';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { FaviconFileUpload } from './FaviconFileUpload';
import { CodeSnippet } from './CodeSnippet';
import { generateFaviconSet } from '@/lib/favicon/faviconService';
import { downloadBlobsAsZip } from '@/lib/media/utils/fileUtils';
import type { FaviconSet, FaviconOptions } from '@/types/favicon';
import { toast } from 'sonner';

export function FaviconGenerator() {
  const [sourceFile, setSourceFile] = React.useState<File | null>(null);
  const [options, setOptions] = React.useState<FaviconOptions>({
    name: 'My Awesome App',
    shortName: 'App',
    backgroundColor: '#ffffff',
    themeColor: '#3b82f6',
  });
  const [isGenerating, setIsGenerating] = React.useState(false);
  const [progress, setProgress] = React.useState(0);
  const [result, setResult] = React.useState<FaviconSet | null>(null);

  const handleGenerate = async () => {
    if (!sourceFile) {
      toast.error('Please upload a source image');
      return;
    }

    setIsGenerating(true);
    setProgress(0);

    try {
      const resultSet = await generateFaviconSet(sourceFile, options, (p) => {
        setProgress(p);
      });
      setResult(resultSet);
      toast.success('Favicon set generated successfully!');
    } catch (error) {
      console.error(error);
      toast.error('Failed to generate favicons');
    } finally {
      setIsGenerating(false);
    }
  };

  const handleDownloadAll = async () => {
    if (!result) return;

    const files = result.icons.map((icon) => ({
      blob: icon.blob!,
      filename: icon.name,
    }));

    // Add manifest to ZIP
    const manifestBlob = new Blob([result.manifest], { type: 'application/json' });
    files.push({
      blob: manifestBlob,
      filename: 'site.webmanifest',
    });

    await downloadBlobsAsZip(files, 'favicons.zip');
    toast.success('Downloading favicons ZIP...');
  };

  const handleReset = () => {
    setSourceFile(null);
    setResult(null);
    setProgress(0);
  };

  return (
    <div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
      {/* Settings Column */}
      <div className="lg:col-span-4 space-y-6">
        <Card>
          <CardHeader>
            <CardTitle>App Details</CardTitle>
          </CardHeader>
          <CardContent className="space-y-3">
            <div className="space-y-1.5">
              <Label htmlFor="app-name" className="text-xs">Application Name</Label>
              <Input
                id="app-name"
                value={options.name}
                onChange={(e) => setOptions({ ...options, name: e.target.value })}
                placeholder="e.g. My Awesome Website"
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="short-name" className="text-xs">Short Name</Label>
              <Input
                id="short-name"
                value={options.shortName}
                onChange={(e) => setOptions({ ...options, shortName: e.target.value })}
                placeholder="e.g. My App"
              />
              <p className="text-[10px] text-muted-foreground">Used for mobile home screen labels</p>
            </div>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Theme Colors</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="grid grid-cols-2 gap-3">
              <div className="space-y-1.5">
                <Label htmlFor="bg-color" className="text-xs">Background</Label>
                <div className="flex gap-2">
                  <Input
                    id="bg-color"
                    type="color"
                    className="w-9 p-1 h-9 shrink-0"
                    value={options.backgroundColor}
                    onChange={(e) => setOptions({ ...options, backgroundColor: e.target.value })}
                  />
                  <Input
                    className="font-mono text-xs"
                    value={options.backgroundColor}
                    onChange={(e) => setOptions({ ...options, backgroundColor: e.target.value })}
                  />
                </div>
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="theme-color" className="text-xs">Theme</Label>
                <div className="flex gap-2">
                  <Input
                    id="theme-color"
                    type="color"
                    className="w-9 p-1 h-9 shrink-0"
                    value={options.themeColor}
                    onChange={(e) => setOptions({ ...options, themeColor: e.target.value })}
                  />
                  <Input
                    className="font-mono text-xs"
                    value={options.themeColor}
                    onChange={(e) => setOptions({ ...options, themeColor: e.target.value })}
                  />
                </div>
              </div>
            </div>
          </CardContent>
        </Card>

        <Card className="overflow-hidden">
          <CardContent>
            <FaviconFileUpload
              selectedFile={sourceFile}
              onFileSelect={setSourceFile}
              onFileRemove={() => setSourceFile(null)}
              disabled={isGenerating}
            />
            <Button
              className="w-full mt-4"
              disabled={!sourceFile || isGenerating}
              onClick={handleGenerate}
            >
              {isGenerating ? (
                <>
                  <Loader2 className="h-3.5 w-3.5 mr-1.5 animate-spin" />
                  Generating... {progress}%
                </>
              ) : (
                'Generate Favicons'
              )}
            </Button>
            {result && (
              <Button
                variant="outline"
                className="w-full mt-2"
                onClick={handleReset}
              >
                Reset
              </Button>
            )}
          </CardContent>
        </Card>
      </div>

      {/* Results Column */}
      <div className="lg:col-span-8 space-y-6">
        {isGenerating ? (
          <Card className="h-full flex flex-col items-center justify-center p-10 space-y-4">
            <Loader2 className="h-6 w-6 text-primary animate-spin" />
            <div className="w-full max-w-xs space-y-2">
              <div className="flex items-center justify-between text-[10px] text-muted-foreground">
                <div className="flex items-center gap-1.5">
                  <span className="font-medium">Processing...</span>
                </div>
                <span className="tabular-nums">{progress}%</span>
              </div>
              <Progress value={progress} className="h-1" />
            </div>
          </Card>
        ) : result ? (
          <div className="space-y-5 animate-fade-in">
            <div className="flex items-center justify-between gap-4">
              <h2 className="text-lg font-bold">Generated Assets</h2>
              <Button onClick={handleDownloadAll}>
                <Download className="mr-1.5 h-3.5 w-3.5" />
                Download ZIP
              </Button>
            </div>

            <Tabs defaultValue="icons" className="w-full">
              <TabsList className="w-full">
                <TabsTrigger value="icons" className="flex items-center gap-1.5">
                  <Layout className="h-3.5 w-3.5" />
                  Icons
                </TabsTrigger>
                <TabsTrigger value="html" className="flex items-center gap-1.5">
                  <Code2 className="h-3.5 w-3.5" />
                  HTML
                </TabsTrigger>
                <TabsTrigger value="manifest" className="flex items-center gap-1.5">
                  <Globe className="h-3.5 w-3.5" />
                  Manifest
                </TabsTrigger>
              </TabsList>

              <TabsContent value="icons" className="mt-4">
                <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
                  {result?.icons.map((icon) => (
                    <Card key={icon.name} className="group overflow-hidden">
                      <div className="p-3 flex flex-col items-center text-center space-y-2">
                        <div className="relative h-16 w-16 flex items-center justify-center bg-muted/50 rounded-lg p-1.5 border border-border/50 group-hover:scale-105 transition-transform duration-200">
                          {icon.previewUrl && (
                            <img
                              src={icon.previewUrl}
                              alt={icon.name}
                              className="max-w-full max-h-full object-contain"
                            />
                          )}
                        </div>
                        <div className="space-y-0.5 w-full">
                          <p className="text-[10px] font-medium text-foreground truncate" title={icon.name}>
                            {icon.name}
                          </p>
                          <p className="text-[10px] text-muted-foreground">
                            {icon.width}x{icon.height} · {(icon.size / 1024).toFixed(1)} KB
                          </p>
                        </div>
                      </div>
                    </Card>
                  ))}
                </div>
              </TabsContent>

              <TabsContent value="html" className="mt-4 space-y-3">
                <div className="space-y-1.5">
                  <Label className="text-xs">Embed in your &lt;head&gt;</Label>
                  {result && <CodeSnippet code={result.htmlCode} />}
                </div>
                <div className="p-3 rounded-lg bg-primary/5 border border-primary/10">
                  <p className="text-[11px] text-muted-foreground leading-relaxed">
                    Place generated files in your site root or update the <code className="text-primary">href</code> paths.
                  </p>
                </div>
              </TabsContent>

              <TabsContent value="manifest" className="mt-4">
                <div className="space-y-1.5">
                  <Label className="text-xs">site.webmanifest</Label>
                  {result && <CodeSnippet code={result.manifest} />}
                </div>
              </TabsContent>
            </Tabs>
          </div>
        ) : null}
      </div>
    </div>
  );
}
