import * as z from "zod";
import { zodResolver } from '@hookform/resolvers/zod';
import React, {useEffect, useState} from 'react';
import {
    Dialog,
    DialogContent,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Separator } from "@/components/ui/separator";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
    Form,
    FormControl,
    FormField,
    FormItem,
    FormLabel,
    FormMessage,
} from "@/components/ui/form";
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from "@/components/ui/select";
import {PlusCircle, X, Maximize2} from 'lucide-react';
import {useForm, useFieldArray} from "react-hook-form";
import {getApplicationList} from '../../../Application/List/service';
import {getExternalSystemList, getJenkinsViewList, getJenkinsJobList, createDeploymentConfig, updateDeploymentConfig} from '../service';
import {getPublishedDefinitions} from '@/pages/Workflow/Definition/service';
import type {ExternalSystem} from '@/pages/Deploy/External/types';
import { Editor } from "@/components/Editor";
import { message } from 'antd';

interface Application {
    id: number;
    appName: string;
    language: string;
}

interface JenkinsView {
    id: number;
    viewName: string;
}

interface JenkinsJob {
    id: number;
    jobName: string;
}

interface EnvVariable {
    key: string;
    value: string;
}

const envKeySchema = z.string()
    .refine(val => {
        // 不能为空
        if (!val) return false;
        // 不能以数字开头
        if (/^\d/.test(val)) return false;
        // 不能以符号开头
        if (/^[^a-zA-Z]/.test(val)) return false;
        // 不能是纯数字
        if (/^\d+$/.test(val)) return false;
        // 不能是纯中文
        if (/^[\u4e00-\u9fa5]+$/.test(val)) return false;
        // 只允许字母、数字和下划线
        return /^[a-zA-Z][a-zA-Z0-9_]*$/.test(val);
    }, "变量名只能以字母开头，且只能包含字母、数字和下划线");

const formSchema = z.object({
    applicationId: z.number().optional(),
    externalSystemId: z.number().optional(),
    jenkinsViewId: z.number().optional(),
    jenkinsJobId: z.number().optional(),
    workflowId: z.number().optional(),
    script: z.string(),
    envs: z.array(z.object({
        key: envKeySchema,
        value: z.string()
    }))
});

type FormValues = z.infer<typeof formSchema>;

interface DeploymentConfigModalProps {
    open: boolean;
    onCancel: () => void;
    onSuccess?: () => void;
    environmentId: number;
    buildType: string;
    initialValues?: {
        id?: number;
        buildVariables?: {
            externalSystemId?: number;
            viewId?: number;
            jobId?: number;
            envs?: Record<string, string>;
            script?: string;
        };
        workflowDefinitionId?: number;
        application?: {
            id: number;
            language: string;
        };
    };
}

const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
    open,
    onCancel,
    onSuccess,
    environmentId,
    buildType,
    initialValues
}) => {
    const [applications, setApplications] = useState<Application[]>([]);
    const [externalSystems, setExternalSystems] = useState<ExternalSystem[]>([]);
    const [jenkinsViews, setJenkinsViews] = useState<JenkinsView[]>([]);
    const [jenkinsJobs, setJenkinsJobs] = useState<JenkinsJob[]>([]);
    const [workflows, setWorkflows] = useState<any[]>([]);
    const [fullscreenEditor, setFullscreenEditor] = useState(false);
    const [isFullscreen, setIsFullscreen] = useState(false);
    const [currentApp, setCurrentApp] = useState<Application | null>(null);
    
    const form = useForm<FormValues>({
        resolver: zodResolver(formSchema),
        defaultValues: {
            applicationId: undefined,
            externalSystemId: undefined,
            jenkinsViewId: undefined,
            jenkinsJobId: undefined,
            workflowId: undefined,
            script: '',
            envs: [{key: '', value: ''}]
        }
    });

    const {fields, append, remove} = useFieldArray({
        control: form.control,
        name: "envs"
    });

    useEffect(() => {
        if (open) {
            // 如果是编辑模式，设置初始值
            if (initialValues) {
                // 设置当前应用
                if (initialValues.application) {
                    setCurrentApp({
                        id: initialValues.application.id,
                        appName: '',  // 这个会在应用列表加载后更新
                        language: initialValues.application.language
                    });
                }

                // 将环境变量对象转换为数组形式
                const envArray = initialValues.buildVariables?.envs
                    ? Object.entries(initialValues.buildVariables.envs).map(([key, value]) => ({
                        key,
                        value
                    }))
                    : [{ key: '', value: '' }];

                // 重置表单值
                form.reset({
                    applicationId: initialValues.application?.id,
                    workflowId: initialValues.workflowDefinitionId,
                    externalSystemId: initialValues.buildVariables?.externalSystemId,
                    jenkinsViewId: initialValues.buildVariables?.viewId,
                    jenkinsJobId: initialValues.buildVariables?.jobId,
                    script: initialValues.buildVariables?.script || '',
                    envs: envArray
                });

                // 加载Jenkins相关数据
                if (initialValues.buildVariables?.externalSystemId) {
                    handleExternalSystemChange(initialValues.buildVariables.externalSystemId);
                }
            } else {
                // 新建模式，重置为默认值
                form.reset({
                    applicationId: undefined,
                    externalSystemId: undefined,
                    jenkinsViewId: undefined,
                    jenkinsJobId: undefined,
                    workflowId: undefined,
                    script: '',
                    envs: [{ key: '', value: '' }]
                });
            }

            // 加载基础数据
            getApplicationList().then(data => {
                setApplications(data);
            });
            getExternalSystemList('JENKINS').then(data => {
                setExternalSystems(data);
            });
            fetchWorkflows();
        }
    }, [open, initialValues]);

    // 获取工作流列表
    const fetchWorkflows = async () => {
        try {
            const data = await getPublishedDefinitions();
            setWorkflows(data);
        } catch (error) {
            console.error('Failed to fetch workflows:', error);
        }
    };

    // 当选择外部系统时获取 View 列表
    const handleExternalSystemChange = async (externalSystemId: number) => {
        form.setValue('externalSystemId', externalSystemId);
        try {
            const data = await getJenkinsViewList(externalSystemId);
            setJenkinsViews(data);
            // 如果是编辑模式且有视图ID，加载任务列表
            const currentViewId = form.getValues('jenkinsViewId');
            if (currentViewId) {
                handleJenkinsViewChange(currentViewId);
            }
        } catch (error) {
            console.error('Failed to get Jenkins views:', error);
        }
    };

    // 当选择视图时获取 Job 列表
    const handleJenkinsViewChange = async (viewId: number) => {
        form.setValue('jenkinsViewId', viewId);
        try {
            const data = await getJenkinsJobList(form.getValues('externalSystemId'), viewId);
            setJenkinsJobs(data);
        } catch (error) {
            console.error('Failed to get Jenkins jobs:', error);
        }
    };

    // 当选择应用时获取应用信息
    const handleApplicationChange = (applicationId: number) => {
        const app = applications.find(app => app.id === applicationId);
        setCurrentApp(app || null);
        form.setValue('applicationId', applicationId);
    };

    const handleSubmit = async (values: FormValues) => {
        try {
            if (!environmentId) {
                message.error('请选择环境');
                return;
            }

            // 将环境变量数组转换为Map格式
            const envMap = values.envs.reduce((acc, {key, value}) => {
                if (key && value) {
                    acc[key] = value;
                }
                return acc;
            }, {} as Record<string, string>);

            const params = {
                id: initialValues?.id,
                environmentId,
                applicationId: values.applicationId,
                languageType: currentApp?.language,
                workflowDefinitionId: values.workflowId,
                buildType,
                buildVariables: {
                    externalSystemId: values.externalSystemId,
                    viewId: values.jenkinsViewId,
                    jobId: values.jenkinsJobId,
                    envs: envMap,
                    script: values.script
                }
            };

            if (initialValues?.id) {
                // 编辑模式
                await updateDeploymentConfig(params);
                message.success('更新成功');
            } else {
                // 新增模式
                await createDeploymentConfig(params);
                message.success('创建成功');
            }
            onSuccess?.();
        } catch (error) {
            console.error('Failed to save deployment config:', error);
            message.error(initialValues?.id ? '更新失败' : '创建失败');
        }
    };

    return (
        <>
            <Dialog open={open} onOpenChange={(open) => !open && onCancel()}>
                <DialogContent className="max-w-[800px] h-[90vh]">
                    <DialogHeader>
                        <DialogTitle>部署配置</DialogTitle>
                    </DialogHeader>
                    <Form {...form}>
                        <form onSubmit={form.handleSubmit(handleSubmit)}>
                            <ScrollArea className="h-[calc(90vh-8rem)]">
                                <div className="space-y-6 pr-6">
                                    <div className="grid grid-cols-2 gap-4">
                                        <FormField
                                            control={form.control}
                                            name="applicationId"
                                            render={({field}) => (
                                                <FormItem>
                                                    <FormLabel>应用名称</FormLabel>
                                                    <Select
                                                        onValueChange={(value) => handleApplicationChange(Number(value))}
                                                        value={field.value?.toString()}
                                                    >
                                                        <FormControl>
                                                            <SelectTrigger>
                                                                <SelectValue placeholder="选择应用"/>
                                                            </SelectTrigger>
                                                        </FormControl>
                                                        <SelectContent>
                                                            {applications.map((app) => (
                                                                <SelectItem key={app.id} value={app.id.toString()}>
                                                                    {app.appName}
                                                                </SelectItem>
                                                            ))}
                                                        </SelectContent>
                                                    </Select>
                                                    <FormMessage/>
                                                </FormItem>
                                            )}
                                        />
                                        <FormField
                                            control={form.control}
                                            name="workflowId"
                                            render={({field}) => (
                                                <FormItem>
                                                    <FormLabel>工作流</FormLabel>
                                                    <Select
                                                        onValueChange={(value) => field.onChange(Number(value))}
                                                        value={field.value?.toString()}
                                                    >
                                                        <FormControl>
                                                            <SelectTrigger>
                                                                <SelectValue placeholder="选择工作流"/>
                                                            </SelectTrigger>
                                                        </FormControl>
                                                        <SelectContent>
                                                            {workflows.map((workflow) => (
                                                                <SelectItem key={workflow.id} value={workflow.id.toString()}>
                                                                    {workflow.name}
                                                                </SelectItem>
                                                            ))}
                                                        </SelectContent>
                                                    </Select>
                                                    <FormMessage/>
                                                </FormItem>
                                            )}
                                        />
                                    </div>

                                    <div className="grid grid-cols-3 gap-4">
                                        <FormField
                                            control={form.control}
                                            name="externalSystemId"
                                            render={({field}) => (
                                                <FormItem>
                                                    <FormLabel>三方系统</FormLabel>
                                                    <Select
                                                        onValueChange={(value) => {
                                                            const numValue = Number(value);
                                                            handleExternalSystemChange(numValue);
                                                        }}
                                                        value={field.value?.toString()}
                                                    >
                                                        <FormControl>
                                                            <SelectTrigger>
                                                                <SelectValue placeholder="选择系统"/>
                                                            </SelectTrigger>
                                                        </FormControl>
                                                        <SelectContent>
                                                            {externalSystems.map((system) => (
                                                                <SelectItem key={system.id}
                                                                          value={system.id.toString()}>
                                                                    {system.name}
                                                                </SelectItem>
                                                            ))}
                                                        </SelectContent>
                                                    </Select>
                                                    <FormMessage/>
                                                </FormItem>
                                            )}
                                        />

                                        <FormField
                                            control={form.control}
                                            name="jenkinsViewId"
                                            render={({field}) => (
                                                <FormItem>
                                                    <FormLabel>Jenkins视图配置</FormLabel>
                                                    <Select
                                                        onValueChange={(value) => {
                                                            const numValue = Number(value);
                                                            handleJenkinsViewChange(numValue);
                                                        }}
                                                        value={field.value?.toString()}
                                                    >
                                                        <FormControl>
                                                            <SelectTrigger>
                                                                <SelectValue placeholder="选择视图"/>
                                                            </SelectTrigger>
                                                        </FormControl>
                                                        <SelectContent>
                                                            {jenkinsViews.map((view) => (
                                                                <SelectItem key={view.id}
                                                                          value={view.id.toString()}>
                                                                    {view.viewName}
                                                                </SelectItem>
                                                            ))}
                                                        </SelectContent>
                                                    </Select>
                                                    <FormMessage/>
                                                </FormItem>
                                            )}
                                        />

                                        <FormField
                                            control={form.control}
                                            name="jenkinsJobId"
                                            render={({field}) => (
                                                <FormItem>
                                                    <FormLabel>Jenkins任务配置</FormLabel>
                                                    <Select
                                                        onValueChange={(value) => field.onChange(Number(value))}
                                                        value={field.value?.toString()}
                                                    >
                                                        <FormControl>
                                                            <SelectTrigger>
                                                                <SelectValue placeholder="选择任务"/>
                                                            </SelectTrigger>
                                                        </FormControl>
                                                        <SelectContent>
                                                            {jenkinsJobs.map((job) => (
                                                                <SelectItem key={job.id}
                                                                          value={job.id.toString()}>
                                                                    {job.jobName}
                                                                </SelectItem>
                                                            ))}
                                                        </SelectContent>
                                                    </Select>
                                                    <FormMessage/>
                                                </FormItem>
                                            )}
                                        />
                                    </div>

                                    <Separator className="my-4"/>

                                    <div className="space-y-4">
                                        <div className="flex items-center justify-between">
                                            <FormLabel>环境变量</FormLabel>
                                            <Button
                                                type="button"
                                                variant="outline"
                                                size="sm"
                                                onClick={() => append({key: '', value: ''})}
                                            >
                                                <PlusCircle className="h-4 w-4 mr-2"/>
                                                添加变量
                                            </Button>
                                        </div>
                                        <ScrollArea className="h-[200px] rounded-md border">
                                            <div className="space-y-4 p-4">
                                                {fields.length === 0 ? (
                                                    <div className="h-[160px] flex flex-col items-center justify-center text-center">
                                                        <div className="w-10 h-10 mb-3 text-muted-foreground/60">
                                                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
                                                                <path d="M20 7h-7M14 17H6M8 7H4M4 17h-2M18 17h4M14 7h8"/>
                                                                <path d="M12 20V4"/>
                                                            </svg>
                                                        </div>
                                                        <div className="text-sm text-muted-foreground/80">暂无环境变量配置</div>
                                                        <div className="text-xs text-muted-foreground/60 mt-1">
                                                            点击"添加变量"开始配置
                                                        </div>
                                                    </div>
                                                ) : (
                                                    fields.map((field, index) => (
                                                        <div key={field.id} className="flex gap-4 items-start">
                                                            <FormField
                                                                control={form.control}
                                                                name={`envs.${index}.key`}
                                                                render={({field}) => (
                                                                    <FormItem className="flex-1">
                                                                        <FormControl>
                                                                            <Input placeholder="变量名" {...field} />
                                                                        </FormControl>
                                                                        <FormMessage/>
                                                                    </FormItem>
                                                                )}
                                                            />
                                                            <FormField
                                                                control={form.control}
                                                                name={`envs.${index}.value`}
                                                                render={({field}) => (
                                                                    <FormItem className="flex-1">
                                                                        <FormControl>
                                                                            <Input placeholder="变量值" {...field} />
                                                                        </FormControl>
                                                                        <FormMessage/>
                                                                    </FormItem>
                                                                )}
                                                            />
                                                            <Button
                                                                type="button"
                                                                variant="ghost"
                                                                size="icon"
                                                                onClick={() => remove(index)}
                                                                className="mt-2"
                                                            >
                                                                <X className="h-4 w-4"/>
                                                            </Button>
                                                        </div>
                                                    ))
                                                )}
                                            </div>
                                        </ScrollArea>
                                    </div>

                                    <Separator className="my-4"/>

                                    <div>
                                        <FormField
                                            control={form.control}
                                            name="script"
                                            render={({field}) => (
                                                <FormItem className="relative">
                                                    <div className="flex items-center justify-between mb-2">
                                                        <FormLabel>部署脚本</FormLabel>
                                                        <Button
                                                            type="button"
                                                            variant="outline"
                                                            size="sm"
                                                        >
                                                            生成配置
                                                        </Button>
                                                    </div>
                                                    <FormControl>
                                                        <div className="relative">
                                                            <Button
                                                                type="button"
                                                                variant="outline"
                                                                size="sm"
                                                                className="absolute right-2 top-2 z-10"
                                                                onClick={() => setIsFullscreen(true)}
                                                            >
                                                                <Maximize2 className="h-4 w-4"/>
                                                            </Button>
                                                            <Editor
                                                                height="300px"
                                                                language="groovy"
                                                                theme="vs-dark"
                                                                value={field.value}
                                                                onChange={field.onChange}
                                                                options={{
                                                                    minimap: { enabled: false },
                                                                    scrollBeyondLastLine: false,
                                                                    fontSize: 14,
                                                                    lineNumbers: 'on',
                                                                    renderLineHighlight: 'all',
                                                                    automaticLayout: true
                                                                }}
                                                            />
                                                        </div>
                                                    </FormControl>
                                                    <FormMessage/>
                                                </FormItem>
                                            )}
                                        />
                                    </div>
                                </div>
                            </ScrollArea>
                            <div className="flex justify-end gap-2 mt-6">
                                <Button variant="outline" onClick={onCancel}>
                                    取消
                                </Button>
                                <Button type="submit">
                                    确定
                                </Button>
                            </div>
                        </form>
                    </Form>
                </DialogContent>
            </Dialog>

            {isFullscreen && (
                <Dialog open={isFullscreen} onOpenChange={setIsFullscreen}>
                    <DialogContent className="max-w-[100vw] w-[100vw] h-[100vh] p-0">
                        <div className="h-full flex flex-col">
                            <div className="flex-shrink-0 p-4 border-b">
                                <DialogTitle>部署脚本编辑</DialogTitle>
                            </div>
                            <div className="flex-1 p-4">
                                <FormField
                                    control={form.control}
                                    name="script"
                                    render={({ field }) => (
                                        <Editor
                                            height="calc(100vh - 120px)"
                                            language="groovy"
                                            theme="vs-dark"
                                            value={field.value}
                                            onChange={(value) => field.onChange(value ?? '')}
                                            options={{
                                                minimap: { enabled: true },
                                                scrollBeyondLastLine: false,
                                                fontSize: 14,
                                                lineNumbers: 'on',
                                                folding: true
                                            }}
                                        />
                                    )}
                                />
                            </div>
                        </div>
                    </DialogContent>
                </Dialog>
            )}
        </>
    );
};

export default DeploymentConfigModal;