'use client';

import { useState } from 'react';
import { TestStep, BrowserConfig, TargetConfig, ConfigItem, TestCaseFile, TEST_CASE_KIND } from '@/types';
import BuilderForm from './BuilderForm';
import ConfigurationsSection from '@/components/features/test-configurations/ConfigurationsSection';
import ConfigHints from '@/components/features/test-configurations/ui/ConfigHints';
import { buildAuthHeaders, buildConfigsEndpoint } from '@/components/features/test-configurations/model/config-utils';
import type { BrowserEntry } from '@/components/features/test-configurations/model/types';
import type { TestData } from '../model/types';
import { useTestFormState } from '../hooks/useTestFormState';
import { buildCurrentData as buildTestData, createStepId, hasMissingRequiredTestingTargetFields } from '../model/state-utils';
import { useI18n } from '@/i18n';
import { useAuth } from '@/app/auth-provider';
import { normalizeBrowserConfig } from '@/lib/test-config/browser-target';

interface TestFormProps {
    onSubmit: (data: TestData) => void;
    isLoading: boolean;
    submitOnEnter?: boolean;
    initialData?: TestData;
    showNameInput?: boolean;
    readOnly?: boolean;
    testCaseId?: string;
    onSaveDraft?: (data: TestData) => Promise<void>;
    onDiscard?: () => void;
    isSaving?: boolean;
    displayId?: string;
    onDisplayIdChange?: (id: string) => void;
    projectId?: string;
    teamId?: string;
    projectConfigs?: ConfigItem[];
    testCaseConfigs?: ConfigItem[];
    testCaseFiles?: TestCaseFile[];
    onTestCaseConfigsChange?: (id?: string) => void;
    onEnsureTestCase?: (data: TestData) => Promise<string | null>;
}

type TestFormTab = 'configurations' | 'test-steps';

const SAMPLE_URL_CONFIG_NAME = 'SAUCEDEMO_URL';
const SAMPLE_URL_CONFIG_VALUE = 'https://www.saucedemo.com';
const SAMPLE_USERNAME_CONFIG_NAME = 'USERNAME';
const SAMPLE_USERNAME_CONFIG_VALUE = 'standard_user';
const SAMPLE_USERNAME_VARIABLE_REF = `{{${SAMPLE_USERNAME_CONFIG_NAME}}}`;
const SAMPLE_PASSWORD_CONFIG_NAME = 'PASSWORD';
const SAMPLE_PASSWORD_CONFIG_VALUE = 'secret_sauce';
const SAMPLE_PASSWORD_VARIABLE_REF = `{{${SAMPLE_PASSWORD_CONFIG_NAME}}}`;

const SAMPLE_CONFIGS_TO_ENSURE = [
    { name: SAMPLE_URL_CONFIG_NAME, type: 'URL', value: SAMPLE_URL_CONFIG_VALUE },
    { name: SAMPLE_USERNAME_CONFIG_NAME, type: 'VARIABLE', value: SAMPLE_USERNAME_CONFIG_VALUE },
    { name: SAMPLE_PASSWORD_CONFIG_NAME, type: 'VARIABLE', value: SAMPLE_PASSWORD_CONFIG_VALUE, masked: true },
] as const;

export default function TestForm({ onSubmit, isLoading, submitOnEnter = true, initialData, showNameInput, readOnly, testCaseId, onSaveDraft, onDiscard, isSaving, displayId, onDisplayIdChange, projectId, teamId, projectConfigs, testCaseConfigs, testCaseFiles, onTestCaseConfigsChange, onEnsureTestCase }: TestFormProps) {
    const { getAccessToken } = useAuth();
    const { t } = useI18n();
    const isLoginFlow = initialData?.kind === TEST_CASE_KIND.LOGIN_FLOW;
    const [activeTab, setActiveTab] = useState<TestFormTab>('configurations');
    const {
        name,
        setName,
        browsers,
        setBrowsers,
        steps,
        setSteps,
    } = useTestFormState({ initialData });

    const ensureSampleConfigs = async (targetTestCaseId?: string) => {
        try {
            const existingNames = new Set(
                (targetTestCaseId ? (testCaseConfigs || []) : [...(projectConfigs || []), ...(testCaseConfigs || [])])
                    .map((cfg) => cfg.name)
            );
            const configsToCreate = SAMPLE_CONFIGS_TO_ENSURE.filter((cfg) => !existingNames.has(cfg.name));
            if (configsToCreate.length === 0) return;

            const token = await getAccessToken();
            const headers = buildAuthHeaders(token, true);
            if (targetTestCaseId) {
                let hasCreatedTestCaseConfig = false;
                for (const cfg of configsToCreate) {
                    const response = await fetch(buildConfigsEndpoint({ kind: 'test-case', id: targetTestCaseId }), {
                        method: 'POST',
                        headers,
                        body: JSON.stringify(cfg)
                    });

                    if (response.ok || response.status === 409) {
                        hasCreatedTestCaseConfig = true;
                    }
                }

                if (hasCreatedTestCaseConfig) {
                    onTestCaseConfigsChange?.(targetTestCaseId);
                }
                return;
            }

            if (projectId) {
                for (const cfg of configsToCreate) {
                    const response = await fetch(buildConfigsEndpoint({ kind: 'project', id: projectId }), {
                        method: 'POST',
                        headers,
                        body: JSON.stringify(cfg)
                    });

                    if (!response.ok && response.status !== 409) {
                        console.error(`Failed to create sample config on project: ${cfg.name}`);
                    }
                }
            }
        } catch (error) {
            console.error('Failed to ensure sample configs', error);
        }
    };

    const handleLoadSampleData = async () => {
        const sampleName = t('sample.multi.name');
        const sampleDisplayId = t('sample.multi.testCaseId');
        const placeholderVars = { username: SAMPLE_USERNAME_VARIABLE_REF, password: SAMPLE_PASSWORD_VARIABLE_REF };
        const sampleBrowsers: BrowserEntry[] = [
            {
                id: 'browser_a',
                config: normalizeBrowserConfig({
                    name: t('sample.multi.browserAName'),
                    url: SAMPLE_URL_CONFIG_VALUE,
                })
            },
            {
                id: 'browser_b',
                config: normalizeBrowserConfig({
                    name: t('sample.multi.browserBName'),
                    url: SAMPLE_URL_CONFIG_VALUE,
                })
            }
        ];
        const sampleSteps: TestStep[] = [
            { id: createStepId('sample'), target: 'browser_a', action: t('sample.multi.step1', placeholderVars), type: 'ai-action' },
            { id: createStepId('sample'), target: 'browser_b', action: t('sample.multi.step2', placeholderVars), type: 'ai-action' },
            { id: createStepId('sample'), target: 'browser_a', action: t('sample.multi.step3'), type: 'ai-action' },
            { id: createStepId('sample'), target: 'browser_b', action: t('sample.multi.step4'), type: 'ai-action' },
            { id: createStepId('sample'), target: 'browser_a', action: t('sample.multi.step5'), type: 'ai-action' },
            { id: createStepId('sample'), target: 'browser_a', action: t('sample.multi.step6'), type: 'ai-action' },
            { id: createStepId('sample'), target: 'browser_a', action: t('sample.multi.step7'), type: 'ai-action' },
            { id: createStepId('sample'), target: 'browser_b', action: t('sample.multi.step8'), type: 'ai-action' },
            { id: createStepId('sample'), target: 'browser_b', action: t('sample.multi.step9'), type: 'ai-action' },
            { id: createStepId('sample'), target: 'browser_b', action: t('sample.multi.step10'), type: 'ai-action' }
        ];

        const sampleBrowserConfig: Record<string, BrowserConfig | TargetConfig> = {};
        sampleBrowsers.forEach((browser) => {
            sampleBrowserConfig[browser.id] = browser.config;
        });

        const sampleData: TestData = {
            name: showNameInput ? sampleName : undefined,
            displayId: sampleDisplayId || undefined,
            kind: initialData?.kind,
            url: SAMPLE_URL_CONFIG_VALUE,
            prompt: '',
            steps: sampleSteps,
            browserConfig: sampleBrowserConfig,
        };

        let targetTestCaseId = testCaseId;
        if (!targetTestCaseId && onEnsureTestCase) {
            const ensured = await onEnsureTestCase(sampleData);
            targetTestCaseId = ensured || undefined;
        }

        await ensureSampleConfigs(targetTestCaseId);

        setName(sampleName);
        setBrowsers(sampleBrowsers);
        setSteps(sampleSteps);
        if (sampleDisplayId) {
            onDisplayIdChange?.(sampleDisplayId);
        }
        setActiveTab('test-steps');
    };

    const getCurrentData = (): TestData => ({
        ...buildTestData(
            browsers,
            steps,
            showNameInput,
            name,
            displayId
        ),
        kind: initialData?.kind,
    });

    const hasMissingRequiredTestCaseId = showNameInput && !readOnly && !displayId?.trim();

    const submitRun = () => {
        if (hasMissingRequiredTestCaseId) {
            setActiveTab('configurations');
            return;
        }
        if (hasMissingRequiredTestingTargetFields(browsers)) {
            setActiveTab('configurations');
            return;
        }
        onSubmit(getCurrentData());
    };

    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault();
        if (!submitOnEnter) {
            return;
        }
        submitRun();
    };

    const runDisabled = isLoading || hasMissingRequiredTestCaseId || hasMissingRequiredTestingTargetFields(browsers);

    return (
        <form onSubmit={handleSubmit} className="glass-panel h-[800px] flex flex-col">
            <div className="p-6 pb-0 border-b border-gray-200">
                <div className="flex items-center justify-between">
                    <h2 className="text-xl font-semibold text-foreground">{isLoginFlow ? t('testForm.title.loginFlow') : t('testForm.title')}</h2>
                </div>

                <div className="mt-4">
                    <div className="flex items-end justify-between gap-4">
                        <nav className="flex gap-6 -mb-px">
                            <button
                                type="button"
                                onClick={() => setActiveTab('configurations')}
                                className={`pb-3 text-sm font-medium border-b-2 transition-colors ${activeTab === 'configurations'
                                    ? 'border-primary text-primary'
                                    : 'border-transparent text-gray-500 hover:text-gray-700'
                                    }`}
                            >
                                {t('testForm.tab.configurations')}
                            </button>
                            <button
                                type="button"
                                onClick={() => setActiveTab('test-steps')}
                                className={`pb-3 text-sm font-medium border-b-2 transition-colors ${activeTab === 'test-steps'
                                    ? 'border-primary text-primary'
                                    : 'border-transparent text-gray-500 hover:text-gray-700'
                                    }`}
                            >
                                {t('testForm.tab.testSteps')}
                            </button>
                        </nav>

                        {!readOnly && !isLoginFlow && (
                            <button
                                type="button"
                                onClick={handleLoadSampleData}
                                className="mb-2 text-xs flex items-center gap-1.5 text-primary hover:text-primary/80 font-medium px-3 py-1.5 rounded-lg hover:bg-primary/10 transition-colors whitespace-nowrap"
                            >
                                <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
                                </svg>
                                {t('testForm.sampleData')}
                            </button>
                        )}
                    </div>
                </div>
            </div>

            <div className="flex-1 overflow-y-auto p-6">
                {activeTab === 'configurations' ? (
                    <div className="space-y-8">
                        {showNameInput && (
                            <div className="space-y-2">
                                <label className="block text-sm font-medium text-foreground">
                                    {isLoginFlow ? t('testForm.loginFlowName') : t('testForm.testCaseName')} {!readOnly && <span className="text-red-500">*</span>}
                                </label>
                                <input
                                    type="text"
                                    required
                                    className="input-field"
                                    placeholder={isLoginFlow ? t('testForm.loginFlowName.placeholder') : t('testForm.testCaseName.placeholder')}
                                    value={name}
                                    onChange={(e) => setName(e.target.value)}
                                    disabled={readOnly}
                                />
                            </div>
                        )}

                        {showNameInput && (onDisplayIdChange || readOnly) && (
                            <div className="space-y-2">
                                <label className="block text-sm font-medium text-foreground">
                                    {isLoginFlow ? t('testForm.loginFlowId') : t('testForm.testCaseId')} {!readOnly && <span className="text-red-500">*</span>}
                                </label>
                                <input
                                    type="text"
                                    className="input-field"
                                    required={!readOnly}
                                    placeholder={isLoginFlow ? t('testForm.loginFlowId.placeholder') : t('testForm.testCaseId.placeholder')}
                                    value={displayId || ''}
                                    onChange={(e) => onDisplayIdChange?.(e.target.value)}
                                    disabled={readOnly}
                                />
                            </div>
                        )}

                        <ConfigurationsSection
                            projectId={projectId}
                            teamId={teamId}
                            projectConfigs={projectConfigs || []}
                            testCaseConfigs={testCaseConfigs || []}
                            testCaseId={testCaseId}
                            onTestCaseConfigsChange={(updatedTestCaseId) => onTestCaseConfigsChange?.(updatedTestCaseId || testCaseId)}
                            onEnsureTestCaseId={onEnsureTestCase ? () => onEnsureTestCase(getCurrentData()) : undefined}
                            readOnly={readOnly}
                            isLoginFlow={isLoginFlow}
                            browsers={browsers}
                            setBrowsers={setBrowsers}
                        />
                    </div>
                ) : (
                    <div className="space-y-4">
                        {!readOnly && (
                            <ConfigHints compact />
                        )}

                        <BuilderForm
                            browsers={browsers}
                            steps={steps}
                            setSteps={setSteps}
                            readOnly={readOnly}
                            projectConfigs={projectConfigs}
                            testCaseConfigs={testCaseConfigs}
                            testCaseFiles={testCaseFiles}
                        />
                    </div>
                )}
            </div>

            {!readOnly && (
                <div className="p-6 pt-4 border-t border-gray-200 bg-white rounded-b-xl space-y-3">
                    {(onDiscard || onSaveDraft) && (
                        <div className="flex gap-3">
                            {onDiscard && (
                                <button
                                    type="button"
                                    onClick={onDiscard}
                                    className="cursor-pointer flex-1 px-4 py-2.5 bg-gray-200 text-gray-700 rounded-lg hover:bg-gray-300 transition-colors font-medium"
                                >
                                    {t('testForm.discard')}
                                </button>
                            )}
                            {onSaveDraft && (
                                <button
                                    type="button"
                                    onClick={() => {
                                        const data = getCurrentData();
                                        onSaveDraft(data);
                                    }}
                                    disabled={isSaving || !name.trim() || hasMissingRequiredTestCaseId}
                                    className="cursor-pointer flex-1 px-4 py-2.5 bg-primary/20 text-primary rounded-lg hover:bg-primary/30 transition-colors font-medium disabled:opacity-50 disabled:cursor-not-allowed flex justify-center items-center gap-2"
                                >
                                    {isSaving ? (
                                        <>
                                            <svg className="animate-spin h-4 w-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                                                <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                                                <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                                            </svg>
                                            <span>{t('testForm.saving')}</span>
                                        </>
                                    ) : (
                                        <span>{t('testForm.saveDraft')}</span>
                                    )}
                                </button>
                            )}
                        </div>
                    )}
                    <button
                        type={submitOnEnter ? 'submit' : 'button'}
                        onClick={submitOnEnter ? undefined : submitRun}
                        disabled={runDisabled}
                        className="btn-primary w-full flex justify-center items-center gap-2 h-11 text-base shadow-lg hover:shadow-xl transition-all"
                    >
                        {isLoading ? (
                            <>
                                <svg className="animate-spin h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                                    <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                                    <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                                </svg>
                                <span>{t('testForm.running')}</span>
                            </>
                        ) : (
                            <>
                                <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                                    <path strokeLinecap="round" strokeLinejoin="round" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
                                    <path strokeLinecap="round" strokeLinejoin="round" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                                </svg>
                                <span>{t('testForm.run')}</span>
                            </>
                        )}
                    </button>
                </div>
            )}
        </form>
    );
}

export type { TestData, TestFormProps };
