'use client';

import { ProTable, ProTableActions } from '@/components/pro-table';
import {
  createSubscribeApplication,
  deleteSubscribeApplication,
  getSubscribeApplicationList,
  updateSubscribeApplication,
} from '@/services/admin/application';
import { zodResolver } from '@hookform/resolvers/zod';
import { ColumnDef } from '@tanstack/react-table';
import { Badge } from '@workspace/ui/components/badge';
import { Button } from '@workspace/ui/components/button';
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@workspace/ui/components/form';
import { Input } from '@workspace/ui/components/input';
import { ScrollArea } from '@workspace/ui/components/scroll-area';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@workspace/ui/components/select';
import {
  Sheet,
  SheetContent,
  SheetFooter,
  SheetHeader,
  SheetTitle,
} from '@workspace/ui/components/sheet';
import { Switch } from '@workspace/ui/components/switch';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@workspace/ui/components/tabs';
import { Textarea } from '@workspace/ui/components/textarea';
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from '@workspace/ui/components/tooltip';
import { ConfirmButton } from '@workspace/ui/custom-components/confirm-button';
import { GoTemplateEditor } from '@workspace/ui/custom-components/editor';
import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input';
import { Icon } from '@workspace/ui/custom-components/icon';
import { UploadImage } from '@workspace/ui/custom-components/upload-image';
import { useTranslations } from 'next-intl';
import Image from 'next/image';
import { useRef, useState } from 'react';
import { useForm } from 'react-hook-form';
import { toast } from 'sonner';
import { z } from 'zod';

// 表单验证规则 - 基于 API.CreateSubscribeApplicationRequest
const createClientFormSchema = (t: any) =>
  z.object({
    name: z.string().min(1, t('form.validation.nameRequired')),
    description: z.string().optional(),
    icon: z.string().optional(),
    user_agent: z.string().min(1, `User-Agent ${t('form.validation.userAgentRequiredSuffix')}`),
    schema: z.string().default(''),
    template: z.string().default(''),
    output_format: z.string().default(''),
    download_link: z.object({
      windows: z.string().optional(),
      mac: z.string().optional(),
      linux: z.string().optional(),
      ios: z.string().optional(),
      android: z.string().optional(),
      harmony: z.string().optional(),
    }),
  });

type ClientFormData = z.infer<ReturnType<typeof createClientFormSchema>>;

export function ProtocolForm() {
  const t = useTranslations('subscribe');
  const [loading, setLoading] = useState(false);
  const [open, setOpen] = useState(false);
  const [editingClient, setEditingClient] = useState<API.SubscribeApplication | null>(null);
  const tableRef = useRef<ProTableActions>(null);

  const clientFormSchema = createClientFormSchema(t);

  const form = useForm<ClientFormData>({
    resolver: zodResolver(clientFormSchema),
    defaultValues: {
      name: '',
      description: '',
      icon: '',
      user_agent: '',
      schema: '',
      template: '',
      output_format: '',
      download_link: {
        windows: '',
        mac: '',
        linux: '',
        ios: '',
        android: '',
        harmony: '',
      },
    },
  });

  // API请求函数
  const request = async (
    pagination: { page: number; size: number },
    filter: Record<string, unknown>,
  ) => {
    const { data } = await getSubscribeApplicationList({
      page: pagination.page,
      size: pagination.size,
    });

    return {
      list: data.data?.list || [],
      total: data.data?.total || 0,
    };
  };

  // 表格列定义
  const columns: ColumnDef<API.SubscribeApplication, any>[] = [
    {
      accessorKey: 'is_default',
      header: t('table.columns.default'),
      cell: ({ row }) => (
        <Switch
          checked={row.original.is_default || false}
          onCheckedChange={async (checked) => {
            await updateSubscribeApplication({
              ...row.original,
              is_default: checked,
            });
            tableRef.current?.refresh();
          }}
        />
      ),
    },
    {
      accessorKey: 'name',
      header: t('table.columns.name'),
      cell: ({ row }) => (
        <div className='flex items-center gap-2'>
          {row.original.icon && (
            <div className='relative h-6 w-6 flex-shrink-0'>
              <Image
                src={row.original.icon}
                alt={row.original.name}
                width={24}
                height={24}
                className='rounded object-contain'
                onError={() => {
                  console.log(`Failed to load image for ${row.original.name}`);
                }}
              />
            </div>
          )}
          <span className='font-medium'>{row.original.name}</span>
        </div>
      ),
    },
    {
      accessorKey: 'description',
      header: t('table.columns.description'),
      cell: ({ row }) => (
        <TooltipProvider>
          <Tooltip>
            <TooltipTrigger>
              <div className='text-muted-foreground max-w-[200px] truncate text-sm'>
                {row.original.description}
              </div>
            </TooltipTrigger>
            <TooltipContent className='max-w-xs'>
              <p>{row.original.description}</p>
            </TooltipContent>
          </Tooltip>
        </TooltipProvider>
      ),
    },
    {
      accessorKey: 'output_format',
      header: t('table.columns.outputFormat'),
      cell: ({ row }) => (
        <Badge variant='secondary' className='text-xs'>
          {t(`outputFormats.${row.original.output_format}`) || row.original.output_format}
        </Badge>
      ),
    },
    {
      accessorKey: 'download_link',
      header: t('table.columns.supportedPlatforms'),
      cell: ({ row }) => {
        return (
          <div className='flex flex-wrap gap-1'>
            {Object.entries(row.original.download_link || {}).map(([key, value]) => {
              if (value) {
                return (
                  <Badge key={key} variant='secondary' className='text-xs'>
                    {t(`platforms.${key}`)}
                  </Badge>
                );
              }
              return null;
            })}
          </div>
        );
      },
    },
    {
      accessorKey: 'user_agent',
      header: 'User-Agent',
      cell: ({ row }) => (
        <div className='text-muted-foreground max-w-[150px] truncate font-mono text-sm'>
          {row.original.user_agent}
        </div>
      ),
    },
  ];

  const handleAdd = () => {
    setEditingClient(null);
    form.reset({
      name: '',
      description: '',
      icon: '',
      user_agent: '',
      schema: '',
      template: '',
      output_format: '',
      download_link: {
        windows: '',
        mac: '',
        linux: '',
        ios: '',
        android: '',
        harmony: '',
      },
    });
    setOpen(true);
  };

  const handleEdit = (client: API.SubscribeApplication) => {
    setEditingClient(client);
    form.reset({
      name: client.name,
      description: client.description || '',
      icon: client.icon || '',
      user_agent: client.user_agent,
      schema: client.proxy_template || '',
      template: client.template || '',
      output_format: client.output_format || '',
      download_link: {
        windows: '',
        mac: '',
        linux: '',
        ios: '',
        android: '',
        harmony: '',
      },
    });
    setOpen(true);
  };

  const handleDelete = async (client: API.SubscribeApplication) => {
    setLoading(true);
    try {
      await deleteSubscribeApplication({ id: client.id });
      tableRef.current?.refresh();
      toast.success(t('actions.deleteSuccess'));
    } catch (error) {
      console.error('Failed to delete client:', error);
      toast.error(t('actions.deleteFailed'));
    } finally {
      setLoading(false);
    }
  };

  const handleBatchDelete = async (clients: API.SubscribeApplication[]) => {
    setLoading(true);
    try {
      await Promise.all(clients.map((client) => deleteSubscribeApplication({ id: client.id })));
      tableRef.current?.refresh();
      toast.success(t('actions.batchDeleteSuccess', { count: clients.length }));
    } catch (error) {
      console.error('Failed to batch delete clients:', error);
      toast.error(t('actions.deleteFailed'));
    } finally {
      setLoading(false);
    }
  };

  const onSubmit = async (data: ClientFormData) => {
    setLoading(true);
    try {
      if (editingClient) {
        await updateSubscribeApplication({
          ...data,
          proxy_template: data.schema || '',
          is_default: editingClient.is_default,
          id: editingClient.id,
        });
        toast.success(t('actions.updateSuccess'));
      } else {
        await createSubscribeApplication({
          ...data,
          proxy_template: data.schema || '',
          is_default: false,
        });
        toast.success(t('actions.createSuccess'));
      }

      setOpen(false);
      tableRef.current?.refresh();
    } catch (error) {
      console.error('Failed to save client:', error);
      toast.error(t('actions.saveFailed'));
    } finally {
      setLoading(false);
    }
  };

  return (
    <>
      <ProTable<API.SubscribeApplication, Record<string, unknown>>
        action={tableRef}
        columns={columns}
        request={request}
        header={{
          title: <h2 className='text-lg font-semibold'>{t('protocol.title')}</h2>,
          toolbar: <Button onClick={handleAdd}>{t('actions.add')}</Button>,
        }}
        actions={{
          render: (row) => [
            <Button
              key='edit'
              onClick={() => handleEdit(row as unknown as API.SubscribeApplication)}
            >
              {t('actions.edit')}
            </Button>,
            <ConfirmButton
              key='delete'
              trigger={
                <Button variant='destructive' disabled={loading}>
                  {t('actions.delete')}
                </Button>
              }
              title={t('actions.confirmDelete')}
              description={t('actions.deleteWarning')}
              onConfirm={() => handleDelete(row as unknown as API.SubscribeApplication)}
              cancelText={t('actions.cancel')}
              confirmText={t('actions.confirm')}
            />,
          ],
          batchRender: (rows) => [
            <ConfirmButton
              key='batchDelete'
              trigger={<Button variant='destructive'>{t('actions.batchDelete')}</Button>}
              title={t('actions.confirmDelete')}
              description={t('actions.batchDeleteWarning', { count: rows.length })}
              onConfirm={() => handleBatchDelete(rows as unknown as API.SubscribeApplication[])}
              cancelText={t('actions.cancel')}
              confirmText={t('actions.confirm')}
            />,
          ],
        }}
      />

      <Sheet open={open} onOpenChange={setOpen}>
        <SheetContent className='w-[580px] max-w-full md:max-w-screen-md'>
          <SheetHeader>
            <SheetTitle>{editingClient ? t('form.editTitle') : t('form.addTitle')}</SheetTitle>
          </SheetHeader>
          <ScrollArea className='h-[calc(100dvh-48px-36px-36px)]'>
            <Form {...form}>
              <form className='space-y-6 py-4'>
                <Tabs defaultValue='basic' className='w-full'>
                  <TabsList className='grid w-full grid-cols-3'>
                    <TabsTrigger value='basic'>{t('form.tabs.basic')}</TabsTrigger>
                    <TabsTrigger value='template'>{t('form.tabs.template')}</TabsTrigger>
                    <TabsTrigger value='download'>{t('form.tabs.download')}</TabsTrigger>
                  </TabsList>

                  <TabsContent value='basic' className='space-y-4'>
                    <FormField
                      control={form.control}
                      name='icon'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>{t('form.fields.icon')}</FormLabel>
                          <FormControl>
                            <EnhancedInput
                              type='text'
                              placeholder='https://example.com/icon.png'
                              suffix={
                                <UploadImage
                                  className='bg-muted h-9 rounded-none border-none px-2'
                                  onChange={(value) => {
                                    form.setValue(field.name, value as string);
                                  }}
                                />
                              }
                              value={field.value}
                              onValueChange={(value) => {
                                form.setValue(field.name, value as string);
                              }}
                            />
                          </FormControl>
                          <FormDescription>{t('form.descriptions.icon')}</FormDescription>
                          <FormMessage />
                        </FormItem>
                      )}
                    />

                    <FormField
                      control={form.control}
                      name='name'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>{t('form.fields.name')}</FormLabel>
                          <FormControl>
                            <Input placeholder='Clash for Windows' {...field} />
                          </FormControl>
                          <FormDescription>{t('form.descriptions.name')}</FormDescription>
                          <FormMessage />
                        </FormItem>
                      )}
                    />

                    <FormField
                      control={form.control}
                      name='user_agent'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>User-Agent</FormLabel>
                          <FormControl>
                            <Input placeholder='Clash' {...field} />
                          </FormControl>
                          <FormDescription>
                            {t('form.descriptions.userAgentPrefix')}
                          </FormDescription>
                          <FormMessage />
                        </FormItem>
                      )}
                    />

                    <FormField
                      control={form.control}
                      name='description'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>{t('form.fields.description')}</FormLabel>
                          <FormControl>
                            <Textarea placeholder={t('form.descriptions.description')} {...field} />
                          </FormControl>
                          <FormDescription>{t('form.descriptions.description')}</FormDescription>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </TabsContent>

                  <TabsContent value='template' className='space-y-4'>
                    <FormField
                      control={form.control}
                      name='output_format'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>{t('form.fields.outputFormat')}</FormLabel>
                          <FormControl>
                            <Select value={field.value} onValueChange={field.onChange}>
                              <SelectTrigger>
                                <SelectValue placeholder='Select ...' />
                              </SelectTrigger>
                              <SelectContent>
                                <SelectItem value='base64'>{t('outputFormats.base64')}</SelectItem>
                                <SelectItem value='yaml'>{t('outputFormats.yaml')}</SelectItem>
                                <SelectItem value='json'>{t('outputFormats.json')}</SelectItem>
                                <SelectItem value='conf'>{t('outputFormats.conf')}</SelectItem>
                                <SelectItem value='plain'>{t('outputFormats.plain')}</SelectItem>
                              </SelectContent>
                            </Select>
                          </FormControl>
                          <FormDescription>{t('form.descriptions.outputFormat')}</FormDescription>
                          <FormMessage />
                        </FormItem>
                      )}
                    />

                    <FormField
                      control={form.control}
                      name='schema'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>{t('form.fields.schema')}</FormLabel>
                          <FormControl>
                            <Input
                              placeholder='clash://install-config?url={url}&name={name}'
                              {...field}
                            />
                          </FormControl>
                          <FormDescription>{t('form.descriptions.schema')}</FormDescription>
                          <FormMessage />
                        </FormItem>
                      )}
                    />

                    <FormField
                      control={form.control}
                      name='template'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>{t('form.fields.template')}</FormLabel>
                          <FormControl>
                            <GoTemplateEditor
                              schema={{
                                SiteName: { type: 'string', description: 'Site name' },
                                SubscribeName: { type: 'string', description: 'Subscribe name' },
                                Nodes: {
                                  type: 'array',
                                  description: 'Array of proxy nodes',
                                  items: {
                                    type: 'object',
                                    properties: {
                                      Name: { type: 'string', description: 'Node name' },
                                      Host: { type: 'string', description: 'Server host' },
                                      Port: { type: 'number', description: 'Server port' },
                                      Type: { type: 'string', description: 'Proxy type' },
                                      Tags: {
                                        type: 'array',
                                        description: 'Node tags',
                                        items: { type: 'string' },
                                      },
                                      SNI: {
                                        type: 'string',
                                        description: 'Server Name Indication',
                                      },
                                      AllowInsecure: {
                                        type: 'boolean',
                                        description: 'Allow insecure connections',
                                      },
                                      Fingerprint: {
                                        type: 'string',
                                        description: 'Client fingerprint',
                                      },
                                      RealityServerAddr: {
                                        type: 'string',
                                        description: 'Reality server address',
                                      },
                                      RealityServerPort: {
                                        type: 'number',
                                        description: 'Reality server port',
                                      },
                                      RealityPrivateKey: {
                                        type: 'string',
                                        description: 'Reality private key',
                                      },
                                      RealityPublicKey: {
                                        type: 'string',
                                        description: 'Reality public key',
                                      },
                                      RealityShortId: {
                                        type: 'string',
                                        description: 'Reality short ID',
                                      },
                                      Network: { type: 'string', description: 'Network protocol' },
                                      Path: { type: 'string', description: 'HTTP path' },
                                      ServiceName: {
                                        type: 'string',
                                        description: 'gRPC service name',
                                      },
                                      Method: { type: 'string', description: 'Encryption method' },
                                      ServerKey: { type: 'string', description: 'Server key' },
                                      Flow: { type: 'string', description: 'Flow control' },
                                      HopPorts: { type: 'string', description: 'Hop ports list' },
                                      HopInterval: {
                                        type: 'number',
                                        description: 'Hop interval in seconds',
                                      },
                                      ObfsPassword: {
                                        type: 'string',
                                        description: 'Obfuscation password',
                                      },
                                    },
                                  },
                                },
                                UserInfo: {
                                  type: 'object',
                                  description: 'User information',
                                  properties: {
                                    Password: { type: 'string', description: 'User password' },
                                    ExpiredAt: { type: 'string', description: 'Expiration date' },
                                    Download: { type: 'number', description: 'Downloaded bytes' },
                                    Upload: { type: 'number', description: 'Uploaded bytes' },
                                    Traffic: { type: 'number', description: 'Total traffic bytes' },
                                    SubscribeURL: {
                                      type: 'string',
                                      description: 'Subscription URL',
                                    },
                                  },
                                },
                              }}
                              enableSprig
                              value={field.value || ''}
                              onChange={(value) => field.onChange(value)}
                            />
                          </FormControl>
                          <FormDescription>{t('form.descriptions.template')}</FormDescription>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </TabsContent>

                  <TabsContent value='download' className='space-y-4'>
                    <div className='space-y-4'>
                      <div className='grid gap-3'>
                        {['windows', 'mac', 'linux', 'ios', 'android', 'harmony'].map((key) => (
                          <FormField
                            key={key}
                            control={form.control}
                            name={
                              `download_link.${key}` as `download_link.${keyof ClientFormData['download_link']}`
                            }
                            render={({ field }) => (
                              <FormItem>
                                <FormLabel>{t(`platforms.${key}`)}</FormLabel>
                                <FormControl>
                                  <Input {...field} />
                                </FormControl>
                                <FormDescription>
                                  {t(`platforms.${key}`)} {t('form.descriptions.downloadLink')}
                                </FormDescription>
                              </FormItem>
                            )}
                          />
                        ))}
                      </div>
                    </div>
                  </TabsContent>
                </Tabs>
              </form>
            </Form>
          </ScrollArea>
          <SheetFooter className='flex-row justify-end gap-2 pt-3'>
            <Button variant='outline' onClick={() => setOpen(false)}>
              {t('actions.cancel')}
            </Button>
            <Button onClick={form.handleSubmit(onSubmit)} disabled={loading}>
              {loading && <Icon icon='mdi:loading' className='mr-2 animate-spin' />}
              {editingClient ? t('actions.update') : t('actions.add')}
            </Button>
          </SheetFooter>
        </SheetContent>
      </Sheet>
    </>
  );
}
