'use client';

import Link from 'next/link';
import { useEffect, useMemo, useState } from 'react';
import { Icons } from '@/components/icons';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { cn } from '@/lib/utils';

type WizardState = {
  appUrl: string;
  authSecret: string;
  dbHost: string;
  dbPort: string;
  dbName: string;
  dbUser: string;
  dbPassword: string;
  superAdminEmail: string;
  superAdminPassword: string;
  superAdminName: string;
  resetPassword: boolean;
  buildStandalone: boolean;
};

const steps = [
  'Project URL',
  'Database',
  'Auth + seed',
  'Preview .env.local'
] as const;

function generateSecret() {
  const bytes = new Uint8Array(32);
  crypto.getRandomValues(bytes);
  return Array.from(bytes, (value) => value.toString(16).padStart(2, '0')).join('');
}

function download(filename: string, content: string) {
  const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement('a');
  anchor.href = url;
  anchor.download = filename;
  anchor.click();
  URL.revokeObjectURL(url);
}

export function SetupWizard() {
  const [copied, setCopied] = useState(false);
  const [state, setState] = useState<WizardState>({
    appUrl: 'http://localhost:3000',
    authSecret: '',
    dbHost: 'localhost',
    dbPort: '5432',
    dbName: 'training_system',
    dbUser: 'postgres',
    dbPassword: 'postgres',
    superAdminEmail: 'admin@example.com',
    superAdminPassword: 'change-this-password',
    superAdminName: 'Super Admin',
    resetPassword: false,
    buildStandalone: false
  });

  useEffect(() => {
    setState((current) =>
      current.authSecret ? current : { ...current, authSecret: generateSecret() }
    );
  }, []);

  const databaseUrl = useMemo(() => {
    const user = encodeURIComponent(state.dbUser);
    const password = encodeURIComponent(state.dbPassword);
    return `postgres://${user}:${password}@${state.dbHost}:${state.dbPort}/${state.dbName}`;
  }, [state.dbHost, state.dbName, state.dbPassword, state.dbPort, state.dbUser]);

  const envContent = useMemo(
    () =>
      [
        '# Generated by /setup',
        '',
        '# Authentication (Auth.js)',
        `AUTH_SECRET=${state.authSecret}`,
        '',
        '# Optional local app URL reference',
        `APP_URL=${state.appUrl}`,
        '',
        '# Database (PostgreSQL)',
        `DATABASE_URL=${databaseUrl}`,
        '',
        '# Initial Super Admin Seed',
        `SUPER_ADMIN_EMAIL=${state.superAdminEmail}`,
        `SUPER_ADMIN_PASSWORD=${state.superAdminPassword}`,
        `SUPER_ADMIN_NAME=${state.superAdminName}`,
        `SUPER_ADMIN_RESET_PASSWORD=${state.resetPassword ? 'true' : 'false'}`,
        '',
        '# Build Configuration',
        `BUILD_STANDALONE=${state.buildStandalone ? 'true' : ''}`,
        '',
        '# Sentry (optional)',
        'NEXT_PUBLIC_SENTRY_DSN=',
        'NEXT_PUBLIC_SENTRY_ORG=',
        'NEXT_PUBLIC_SENTRY_PROJECT=',
        'SENTRY_AUTH_TOKEN=',
        'NEXT_PUBLIC_SENTRY_DISABLED="false"'
      ].join('\n'),
    [databaseUrl, state]
  );

  async function copyToClipboard() {
    await navigator.clipboard.writeText(envContent);
    setCopied(true);
    window.setTimeout(() => setCopied(false), 2000);
  }

  const completedSteps = [
    !!state.appUrl.trim(),
    !!state.dbHost.trim() && !!state.dbPort.trim() && !!state.dbName.trim(),
    !!state.authSecret.trim() && !!state.superAdminEmail.trim() && !!state.superAdminPassword.trim(),
    true
  ].filter(Boolean).length;

  return (
    <div className='min-h-screen bg-[linear-gradient(135deg,_hsl(var(--background))_20%,_hsl(var(--muted)/0.35)),radial-gradient(circle_at_top_right,_hsl(var(--primary)/0.16),_transparent_32%)]'>
      <div className='mx-auto max-w-7xl px-4 py-10 md:px-6'>
        <div className='grid gap-6 xl:grid-cols-[1.1fr_0.9fr]'>
          <div className='space-y-6'>
            <div className='space-y-4'>
              <Badge variant='outline' className='rounded-full px-3 py-1'>
                Template onboarding
              </Badge>
              <div className='space-y-3'>
                <h1 className='max-w-3xl text-4xl font-semibold tracking-tight md:text-6xl'>
                  Configure the template, then jump straight into the example dashboard.
                </h1>
                <p className='max-w-2xl text-base leading-7 text-muted-foreground md:text-lg'>
                  This setup wizard collects your local database and Auth.js seed values, generates
                  a ready-to-use <code>.env.local</code>, and points you to the public example
                  routes under <code>/example/dashboard/*</code>.
                </p>
              </div>
            </div>

            <div className='grid gap-4 md:grid-cols-2'>
              <Card className='rounded-3xl border-border/60 bg-background/75 backdrop-blur-sm'>
                <CardHeader>
                  <CardTitle className='flex items-center gap-2'>
                    <Icons.settings className='h-5 w-5' />
                    Local app
                  </CardTitle>
                  <CardDescription>Reference URL used during local development.</CardDescription>
                </CardHeader>
                <CardContent className='space-y-2'>
                  <Label htmlFor='appUrl'>App URL</Label>
                  <Input
                    id='appUrl'
                    value={state.appUrl}
                    onChange={(event) => setState({ ...state, appUrl: event.target.value })}
                    placeholder='http://localhost:3000'
                  />
                </CardContent>
              </Card>

              <Card className='rounded-3xl border-border/60 bg-background/75 backdrop-blur-sm'>
                <CardHeader>
                  <CardTitle className='flex items-center gap-2'>
                    <Icons.lock className='h-5 w-5' />
                    Auth secret
                  </CardTitle>
                  <CardDescription>Generated automatically for Auth.js credentials flow.</CardDescription>
                </CardHeader>
                <CardContent className='space-y-3'>
                  <Input
                    value={state.authSecret}
                    onChange={(event) => setState({ ...state, authSecret: event.target.value })}
                  />
                  <Button
                    type='button'
                    variant='outline'
                    className='rounded-2xl'
                    onClick={() => setState({ ...state, authSecret: generateSecret() })}
                  >
                    <Icons.sparkles className='mr-2 h-4 w-4' />
                    Regenerate secret
                  </Button>
                </CardContent>
              </Card>
            </div>

            <Card className='rounded-[28px] border-border/60 bg-background/80 shadow-xl backdrop-blur-sm'>
              <CardHeader>
                <CardTitle>Database configuration</CardTitle>
                <CardDescription>
                  Fill in the PostgreSQL connection details. The wizard will build
                  <code> DATABASE_URL</code> for you.
                </CardDescription>
              </CardHeader>
              <CardContent className='grid gap-4 md:grid-cols-2 xl:grid-cols-3'>
                <div className='space-y-2'>
                  <Label htmlFor='dbHost'>Host</Label>
                  <Input
                    id='dbHost'
                    value={state.dbHost}
                    onChange={(event) => setState({ ...state, dbHost: event.target.value })}
                  />
                </div>
                <div className='space-y-2'>
                  <Label htmlFor='dbPort'>Port</Label>
                  <Input
                    id='dbPort'
                    value={state.dbPort}
                    onChange={(event) => setState({ ...state, dbPort: event.target.value })}
                  />
                </div>
                <div className='space-y-2'>
                  <Label htmlFor='dbName'>Database name</Label>
                  <Input
                    id='dbName'
                    value={state.dbName}
                    onChange={(event) => setState({ ...state, dbName: event.target.value })}
                  />
                </div>
                <div className='space-y-2'>
                  <Label htmlFor='dbUser'>Database user</Label>
                  <Input
                    id='dbUser'
                    value={state.dbUser}
                    onChange={(event) => setState({ ...state, dbUser: event.target.value })}
                  />
                </div>
                <div className='space-y-2'>
                  <Label htmlFor='dbPassword'>Database password</Label>
                  <Input
                    id='dbPassword'
                    type='password'
                    value={state.dbPassword}
                    onChange={(event) => setState({ ...state, dbPassword: event.target.value })}
                  />
                </div>
                <div className='space-y-2 md:col-span-2 xl:col-span-1'>
                  <Label htmlFor='databaseUrlPreview'>DATABASE_URL preview</Label>
                  <Input id='databaseUrlPreview' value={databaseUrl} readOnly />
                </div>
              </CardContent>
            </Card>

            <Card className='rounded-[28px] border-border/60 bg-background/80 shadow-xl backdrop-blur-sm'>
              <CardHeader>
                <CardTitle>Initial super admin seed</CardTitle>
                <CardDescription>
                  These values feed the seed script used by <code>npm run setup:db</code>.
                </CardDescription>
              </CardHeader>
              <CardContent className='grid gap-4 md:grid-cols-2'>
                <div className='space-y-2'>
                  <Label htmlFor='superAdminEmail'>Email</Label>
                  <Input
                    id='superAdminEmail'
                    value={state.superAdminEmail}
                    onChange={(event) =>
                      setState({ ...state, superAdminEmail: event.target.value })
                    }
                  />
                </div>
                <div className='space-y-2'>
                  <Label htmlFor='superAdminPassword'>Password</Label>
                  <Input
                    id='superAdminPassword'
                    type='password'
                    value={state.superAdminPassword}
                    onChange={(event) =>
                      setState({ ...state, superAdminPassword: event.target.value })
                    }
                  />
                </div>
                <div className='space-y-2'>
                  <Label htmlFor='superAdminName'>Display name</Label>
                  <Input
                    id='superAdminName'
                    value={state.superAdminName}
                    onChange={(event) =>
                      setState({ ...state, superAdminName: event.target.value })
                    }
                  />
                </div>
                <div className='space-y-2'>
                  <Label htmlFor='resetPassword'>Seed behavior</Label>
                  <div className='flex h-10 items-center rounded-xl border px-3 text-sm text-muted-foreground'>
                    <input
                      id='resetPassword'
                      type='checkbox'
                      aria-label='Reset the seeded super admin password on reruns'
                      checked={state.resetPassword}
                      onChange={(event) =>
                        setState({ ...state, resetPassword: event.target.checked })
                      }
                      className='mr-3'
                    />
                    Reset the seeded super admin password on reruns
                  </div>
                </div>
                <div className='space-y-2'>
                  <Label htmlFor='buildStandalone'>Build mode</Label>
                  <div className='flex h-10 items-center rounded-xl border px-3 text-sm text-muted-foreground'>
                    <input
                      id='buildStandalone'
                      type='checkbox'
                      aria-label='Enable standalone build output'
                      checked={state.buildStandalone}
                      onChange={(event) =>
                        setState({ ...state, buildStandalone: event.target.checked })
                      }
                      className='mr-3'
                    />
                    Enable standalone output for Docker-oriented builds
                  </div>
                </div>
              </CardContent>
            </Card>
          </div>

          <div className='space-y-6'>
            <Card className='rounded-[28px] border-border/60 bg-background/85 shadow-xl backdrop-blur-sm'>
              <CardHeader>
                <CardTitle className='flex items-center justify-between gap-4'>
                  <span>.env.local preview</span>
                  <Badge variant='secondary'>{completedSteps}/{steps.length} steps ready</Badge>
                </CardTitle>
                <CardDescription>
                  Copy or download this file, then run <code>npm run setup:db</code>.
                </CardDescription>
              </CardHeader>
              <CardContent className='space-y-4'>
                <Textarea
                  value={envContent}
                  readOnly
                  className='min-h-[420px] rounded-2xl font-mono text-xs'
                />
                <div className='flex flex-wrap gap-3'>
                  <Button type='button' className='rounded-2xl' onClick={copyToClipboard}>
                    <Icons.check className='mr-2 h-4 w-4' />
                    {copied ? 'Copied' : 'Copy .env.local'}
                  </Button>
                  <Button
                    type='button'
                    variant='outline'
                    className='rounded-2xl'
                    onClick={() => download('.env.local', envContent)}
                  >
                    <Icons.upload className='mr-2 h-4 w-4' />
                    Download file
                  </Button>
                  <Button asChild variant='secondary' className='rounded-2xl'>
                    <Link href='/example/dashboard/overview'>
                      <Icons.arrowRight className='mr-2 h-4 w-4' />
                      Open example dashboard
                    </Link>
                  </Button>
                </div>
              </CardContent>
            </Card>

            <Card className='rounded-[28px] border-border/60 bg-background/75 backdrop-blur-sm'>
              <CardHeader>
                <CardTitle>Next steps</CardTitle>
                <CardDescription>Suggested flow after generating the env file.</CardDescription>
              </CardHeader>
              <CardContent className='space-y-4'>
                {steps.map((step, index) => (
                  <div key={step} className='flex items-start gap-3'>
                    <div
                      className={cn(
                        'mt-0.5 flex h-7 w-7 items-center justify-center rounded-full border text-xs font-semibold',
                        index < completedSteps
                          ? 'bg-primary text-primary-foreground border-primary'
                          : 'text-muted-foreground'
                      )}
                    >
                      {index + 1}
                    </div>
                    <div>
                      <p className='font-medium'>{step}</p>
                      <p className='text-sm text-muted-foreground'>
                        {index === 0 && 'Confirm the URL you will use locally while iterating.'}
                        {index === 1 && 'Provide PostgreSQL connection details for local development.'}
                        {index === 2 &&
                          'Set credentials and seed values for the first super admin account.'}
                        {index === 3 &&
                          'Copy the generated file, run the seed command, then inspect /example/dashboard/*.'}
                      </p>
                    </div>
                  </div>
                ))}
                <div className='rounded-2xl border border-dashed p-4 text-sm text-muted-foreground'>
                  After saving <code>.env.local</code>, run <code>npm run setup:db</code>, then
                  <code> npm run dev</code>. The app will continue to open on <code>/setup</code>,
                  while all public showcase pages live under <code>/example/dashboard/*</code>.
                </div>
              </CardContent>
            </Card>
          </div>
        </div>
      </div>
    </div>
  );
}
