import React, {useCallback, useEffect, useState} from 'react';
import {Button} from '@/components/ui/button';
import {Tabs, TabsContent, TabsList, TabsTrigger} from '@/components/ui/tabs';
import ServerManager from '@/components/shared/ServerManager';
import {useAPI} from '@/providers/APIProvider';
import MonacoEditor from '@/components/shared/MonacoEditor';
import APIClient from '@/services/APIClient';
import {SidebarTrigger} from '@/components/ui/sidebar.jsx';
import {Separator} from '@/components/ui/separator.jsx';
import LayoutGrid from '@/components/layout/LayoutGrid.jsx';
import ApiLayoutItemTreeBuilder from '@/lib/ApiLayoutItemTreeBuilder.js';
import ApiLayoutItemTreeDataBuilder from '@/lib/ApiLayoutItemTreeDataBuilder.js';

export const TCPClientView = ({model, index}) => {
  const apiClient = new APIClient();
  const {getServer, updateAPIRequest} = useAPI();
  const [isLoading, setIsLoading] = useState(false);
  const [currentModel, setCurrentModel] = useState(model);
  const [currentTab, setCurrentTab] = useState('body');
  const [currentResponseTab, setCurrentResponseTab] = useState('response-body');

  useEffect(() => {
    setCurrentModel(prev => ({
      ...prev,
      requestBody: model.requestBody || '',
      layout: model.layout || {},
      contentType: 'plaintext'
    }));
  }, [model]);


  const [layoutRoot, setLayoutRoot] = useState(() => {
    const root = ApiLayoutItemTreeBuilder.createTree(model.layout.layoutItems);
    const replicator = new ApiLayoutItemTreeDataBuilder(10000);
    return replicator.createReplicatedTree(root);
  });

  const [responseData, setResponseData] = useState({
    headers: [],
    status: '',
    time: '',
    size: ''
  });

  const [editorContents, setEditorContents] = useState({
    requestBody: currentModel.requestBody || '',
    responseBody: '',
    consoleLog: '',
    layout: JSON.stringify(currentModel.layout, null, 2) || '',
    preRequestScript: currentModel.preRequestScript || '',
    postRequestScript: currentModel.postRequestScript || ''
  });

  useEffect(() => {
    if (currentModel.server) {
      const selectedServer = getServer(currentModel.server);
    }
  }, [currentModel.server]);

  const handleServerChange = (serverId) => {
    setCurrentModel(prev => ({
      ...prev,
      server: serverId
    }));
  };

  const handleSendRequest = async () => {
    if (isLoading) {
      return;
    }

    setIsLoading(true);
    setEditorContents(prev => ({...prev, consoleLog: ''}));

    try {
      const response = await apiClient.sendAPIRequest(
          currentModel,
          (log) => setEditorContents(prev => ({
            ...prev,
            consoleLog: prev.consoleLog + log + '\n'
          }))
      );

      setResponseData({
        time: `${response.time}ms`,
        size: `Size: ${response.size}`
      });

      setEditorContents(prev => ({
        ...prev,
        responseBody: response.body
      }));


    } catch (error) {
      console.error(error);
      setEditorContents(prev => ({
        ...prev,
        consoleLog: prev.consoleLog + `Error: ${error.message}\n`
      }));
    } finally {
      setIsLoading(false);
    }
  };

  const handleSave = async () => {
    try {
      const updatedModel = {
        ...currentModel,
        preRequestScript: editorContents.preRequestScript,
        postRequestScript: editorContents.postRequestScript,
        layout: JSON.parse(editorContents.layout),
        requestBody: currentModel.requestBody
      };

      await updateAPIRequest(updatedModel);
    } catch (error) {
      console.error('Failed to save API:', error);
    }
  };

  const handleLayoutUpdate = useCallback((updatedLayout) => {
    const updatedRoot = ApiLayoutItemTreeBuilder.createTree(updatedLayout.layoutItems);
    const replicator = new ApiLayoutItemTreeDataBuilder(10000);
    const newRoot = replicator.createReplicatedTree(updatedRoot);
    setLayoutRoot(newRoot);
    currentModel.layout = updatedLayout;
  }, [currentModel]);

  return (
      <div className="flex flex-col h-full p-4 gap-4">
        {/* Request Header Section */}
        <div className="flex items-center gap-2">
          <SidebarTrigger className="-ml-1" />
          <Separator orientation="vertical" className="mr-2 h-4" />
          <div>
            <span>{currentModel.collectionName}</span>
            {' > '}
            <span>{currentModel.name}</span>
          </div>
        </div>

        {/* Request Controls */}
        <div className="flex items-center gap-2">
          <div className="shrink-0">
            <ServerManager
                onServerChange={handleServerChange}
                defaultValue={currentModel.server}
            />
          </div>
          <div className="flex gap-2 shrink-0">
            <Button disabled={isLoading} onClick={handleSendRequest}>
              {isLoading ? 'Sending...' : 'Send'}
            </Button>
            <Button variant="secondary" onClick={handleSave}>Save</Button>
          </div>
        </div>

        {/* Request/Response Container */}
        <div className="flex flex-col gap-4 flex-1 min-h-0">
          {/* Request Section */}
          <div className="flex-1 min-h-0">
            <Tabs value={currentTab} onValueChange={setCurrentTab} className="flex flex-col h-full">
              <TabsList>
                <TabsTrigger value="body">Layout</TabsTrigger>
                <TabsTrigger value="layout-json">Layout JSON</TabsTrigger>
                <TabsTrigger value="pre-request">Pre-Request</TabsTrigger>
                <TabsTrigger value="post-request">Post-Request</TabsTrigger>
              </TabsList>

              <div className="flex-1 min-h-0 mt-2">
                {/* Body Tab Content */}
                <TabsContent value="body" className="h-full m-0">
                  <div className="flex flex-col h-full gap-2">
                    <div className="h-[calc(100%-40px)]">
                      <LayoutGrid
                          layout={currentModel.layout}
                          onChange={handleLayoutUpdate}
                      />
                      <MonacoEditor
                          id={`request-body-${model.id}`}
                          value={currentModel.requestBody}
                          language="plaintext"
                          onChange={(newValue) => {
                            setCurrentModel(prev => ({
                              ...prev,
                              requestBody: newValue
                            }));
                          }}
                      />
                    </div>
                  </div>
                </TabsContent>
                <TabsContent value="layout-json" className="h-full m-0">
                  <MonacoEditor
                      id={`layout-json-${model.id}`}
                      value={editorContents.layout}
                      language="json"
                      onChange={(value) => {
                        setEditorContents(prev => ({...prev, layout: value}));
                        setCurrentModel(prev => ({...prev, layout: JSON.parse(value)}));
                      }}
                      height="full"
                  />
                </TabsContent>
                <TabsContent value="pre-request" className="h-full m-0">
                  <MonacoEditor
                      id={`pre-request-${model.id}`}
                      value={editorContents.preRequestScript}
                      language="javascript"
                      onChange={(value) => {
                        setEditorContents(prev => ({...prev, preRequestScript: value}));
                        setCurrentModel(prev => ({...prev, preRequestScript: value}));
                      }}
                      height="full"
                  />
                </TabsContent>

                {/* Post-Request Tab Content */}
                <TabsContent value="post-request" className="h-full m-0">
                  <MonacoEditor
                      id={`post-request-${model.id}`}
                      value={editorContents.postRequestScript}
                      language="javascript"
                      onChange={(value) => {
                        setEditorContents(prev => ({...prev, postRequestScript: value}));
                        setCurrentModel(prev => ({...prev, postRequestScript: value}));
                      }}
                      height="full"
                  />
                </TabsContent>
              </div>
            </Tabs>
          </div>

          <Separator/>
          {/* Response Section */}
          <div className="flex-1 min-h-0">
            <div className="flex items-center gap-2 mb-2">
              <span>Response</span>
              <span className="text-sm text-gray-500">{responseData.status}</span>
              <span className="text-sm text-gray-500">{responseData.time}</span>
              <span className="text-sm text-gray-500">{responseData.size}</span>
            </div>

            <Tabs value={currentResponseTab} onValueChange={setCurrentResponseTab} className="flex flex-col h-[calc(100%-1rem)]">
              <TabsList>
                <TabsTrigger value="response-body">Body</TabsTrigger>
                <TabsTrigger value="console">Console</TabsTrigger>
              </TabsList>

              <div className="flex-1 min-h-0 mt-1">
                <TabsContent value="response-body" className="h-full m-0">
                  <MonacoEditor
                      id={`response-body-${model.id}`}
                      value={editorContents.responseBody}
                      readOnly={true}
                      height="full"
                  />
                </TabsContent>
                <TabsContent value="console" className="h-full m-0">
                  <MonacoEditor
                      id={`console-${model.id}`}
                      value={editorContents.consoleLog}
                      language="plaintext"
                      readOnly={true}
                      height="full"
                  />
                </TabsContent>
              </div>
            </Tabs>
          </div>
        </div>


      </div>
  );
};

export default TCPClientView;
