import React, { useState, useEffect, useCallback } from 'react';
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Input } from "@/components/ui/input";
import { useMonaco } from '@/hooks/useMonaco';
import EditableInput from '../shared/EditableInput';
import PropertyTable from '../shared/PropertyTable';
import LayoutGrid from '../layout/LayoutGrid';
import LayoutTreeGrid from '../layout/LayoutTreeGrid';
import LayoutTreeDataGrid from '../layout/LayoutTreeDataGrid';
import ApiLayoutItemTreeBuilder from '../../lib/ApiLayoutItemTreeBuilder';
import ApiLayoutItemTreeDataBuilder from '../../lib/ApiLayoutItemTreeDataBuilder';
import VariableSnippet from '../shared/VariableSnippet';

const HTTP_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS', 'TRACE'];

export const HTTPFlatClientView = ({ parent, serverManager, model, index }) => {
  // State
  const [currentTab, setCurrentTab] = useState('layout');
  const [path, setPath] = useState(model.path || '');
  const [queryParams, setQueryParams] = useState(model.queryParams || []);
  const [headers, setHeaders] = useState(model.headers || []);
  const [method, setMethod] = useState(model.method || 'GET');
  const [server, setServer] = useState(model.server);
  const [totalMessageLength, setTotalMessageLength] = useState(0);

  // Editor refs and state
  const { editor: layoutJsonEditor, containerRef: layoutJsonRef } = useMonaco({
    defaultValue: JSON.stringify(model.layout, null, 2),
    language: 'json'
  });

  const { editor: requestBodyEditor, containerRef: requestBodyRef } = useMonaco({
    defaultValue: model.requestBody || '',
    language: 'json'
  });

  const { editor: responseBodyEditor, containerRef: responseBodyRef } = useMonaco({
    defaultValue: '',
    language: 'json',
    readOnly: true
  });

  const { editor: preRequestEditor, containerRef: preRequestRef } = useMonaco({
    defaultValue: model.preRequestScript || '',
    language: 'javascript'
  });

  const { editor: postRequestEditor, containerRef: postRequestRef } = useMonaco({
    defaultValue: model.postRequestScript || '',
    language: 'javascript'
  });

  const { editor: consoleEditor, containerRef: consoleRef } = useMonaco({
    defaultValue: '',
    language: 'text',
    readOnly: true
  });

  // Layout tree options and state
  const layoutDataTreeOptions = [
    { name: 'loutItemSerno', width: 100, isFirst: true, label: '#' },
    { name: 'loutItemName', width: 100, align: 'left', label: '항목명(영문)' },
    { name: 'loutItemDesc', width: 100, align: 'left', label: '항목설명' },
    { name: 'loutItemDepth', width: 60, align: 'center', label: '깊이' },
    { name: 'loutItemType', width: 100, align: 'center', label: '아이템 유형' },
    { name: 'loutItemOccCnt', width: 100, align: 'center', label: '반복 횟수' },
    { name: 'loutItemOccRef', width: 120, align: 'center', label: '반복 참조 필드' },
    { name: 'loutItemLength', width: 100, align: 'center', label: '데이터 길이' },
    { name: 'value', width: 200, align: 'left', label: '값', type: 'textfield' }
  ];

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

  // Handlers
  const handlePathChange = useCallback((newPath) => {
    setPath(newPath);
    const newParams = parent.parseParam(newPath);
    setQueryParams(newParams);
    model.path = newPath;
    model.queryParams = newParams;
  }, [parent, model]);

  const handleServerChange = useCallback((newServer) => {
    setServer(newServer);
    model.server = newServer;
  }, [model]);

  const handleMethodChange = useCallback((newMethod) => {
    setMethod(newMethod);
    model.method = newMethod;
  }, [model]);

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

  const handleLayoutDataChange = useCallback(async (finalMessage, layoutDataTree) => {
    if (requestBodyEditor) {
      const prefix = server && server.serverOptions
          ? await serverManager.renderServerPrefix(server.serverOptions, model)
          : '';
      requestBodyEditor.setValue(prefix + finalMessage);
    }
    model.layout.computedLayoutItemRoot = layoutDataTree;
  }, [server, serverManager, model, requestBodyEditor]);

  const handleSend = useCallback(async () => {
    // Implement send logic
  }, [/* dependencies */]);

  const handleSave = useCallback(() => {
    // Implement save logic
  }, [/* dependencies */]);

  // Effect for editor cleanup
  useEffect(() => {
    return () => {
      // Cleanup logic for editors if needed
    };
  }, []);

  return (
      <div className="flex flex-col h-full gap-4 p-4">
        {/* Header */}
        <div className="text-sm text-muted-foreground">
          {model.collectionName} &gt; {model.name}
        </div>

        {/* Request Controls */}
        <div className="flex items-center gap-2">
          <Select value={method} onValueChange={handleMethodChange}>
            <SelectTrigger className="w-[90px]">
              <SelectValue placeholder="Method" />
            </SelectTrigger>
            <SelectContent>
              {HTTP_METHODS.map(m => (
                  <SelectItem key={m} value={m}>{m}</SelectItem>
              ))}
            </SelectContent>
          </Select>

          <Select value={server} onValueChange={handleServerChange}>
            <SelectTrigger className="w-[180px]">
              <SelectValue placeholder="Server" />
            </SelectTrigger>
            <SelectContent>
              {serverManager.renderHttpServers(server)}
            </SelectContent>
          </Select>

          <Input
              value={serverManager.basePath(server)}
              readOnly
              className="w-[180px]"
          />

          <div className="flex-1">
            <EditableInput
                name="path"
                value={path}
                onChange={handlePathChange}
            />
          </div>

          <Button onClick={handleSend}>Send</Button>
          <Button variant="secondary" onClick={handleSave}>Save</Button>
        </div>

        {/* Main Content */}
        <Tabs value={currentTab} onValueChange={setCurrentTab} className="flex-1">
          <TabsList>
            <TabsTrigger value="layout">Layout</TabsTrigger>
            <TabsTrigger value="layoutJson">Layout JSON</TabsTrigger>
            <TabsTrigger value="layoutTree">Layout Tree</TabsTrigger>
            <TabsTrigger value="layoutData">Layout Data</TabsTrigger>
            <TabsTrigger value="param">Param</TabsTrigger>
            <TabsTrigger value="header">Header</TabsTrigger>
            <TabsTrigger value="preRequest">Pre-Request</TabsTrigger>
            <TabsTrigger value="postRequest">Post-Request</TabsTrigger>
          </TabsList>

          <TabsContent value="layout" className="flex-1">
            <LayoutGrid
                layout={model.layout}
                onChange={handleLayoutUpdate}
            />
          </TabsContent>

          <TabsContent value="layoutJson" className="flex-1">
            <div ref={layoutJsonRef} className="h-[300px] border" />
            <Button
                onClick={() => {/* Implement load layout */}}
                className="mt-2"
            >
              Load Layout
            </Button>
          </TabsContent>

          <TabsContent value="layoutTree" className="flex-1">
            <LayoutTreeGrid
                root={layoutRoot}
                options={layoutDataTreeOptions}
                onChange={handleLayoutUpdate}
            />
          </TabsContent>

          <TabsContent value="layoutData" className="flex-1">
            <LayoutTreeDataGrid
                root={layoutRoot}
                apiRequest={model}
                options={layoutDataTreeOptions}
                onUpdate={handleLayoutDataChange}
                totalMessageLengthSelector={totalMessageLength}
            />
          </TabsContent>

          <TabsContent value="param" className="flex-1">
            <PropertyTable
                properties={queryParams}
                onChange={setQueryParams}
            />
          </TabsContent>

          <TabsContent value="header" className="flex-1">
            <PropertyTable
                properties={headers}
                onChange={setHeaders}
            />
          </TabsContent>

          <TabsContent value="preRequest" className="flex-1">
            <div className="grid grid-cols-[1fr,200px] gap-4">
              <div ref={preRequestRef} className="h-[300px] border" />
              <VariableSnippet editor={preRequestEditor} />
            </div>
          </TabsContent>

          <TabsContent value="postRequest" className="flex-1">
            <div className="grid grid-cols-[1fr,200px] gap-4">
              <div ref={postRequestRef} className="h-[300px] border" />
              <VariableSnippet editor={postRequestEditor} />
            </div>
          </TabsContent>
        </Tabs>

        {/* Request Body */}
        <div className="h-[150px] border">
          <div ref={requestBodyRef} className="h-full" />
        </div>

        {/* Total Message Length */}
        <div className="text-sm">
          Total Message Length: {totalMessageLength}
        </div>

        {/* Response Section */}
        <Card className="flex-1">
          <Tabs defaultValue="body" className="h-full">
            <TabsList>
              <TabsTrigger value="body">Body</TabsTrigger>
              <TabsTrigger value="console">Console</TabsTrigger>
            </TabsList>

            <TabsContent value="body" className="flex-1">
              <div ref={responseBodyRef} className="h-[250px] border" />
            </TabsContent>

            <TabsContent value="console" className="flex-1">
              <div ref={consoleRef} className="h-[250px] border" />
            </TabsContent>
          </Tabs>
        </Card>
      </div>
  );
};

// export default HTTPFlatClientView;
