// mock-git-data-service.ts
// Mock implementation of GitDataService for the demo environment

import { GitDataService, GitDiffFile } from "../git-data-service";
import { GitLogEntry } from "../../types";

/**
 * Demo implementation of GitDataService with canned responses
 */
export class MockGitDataService implements GitDataService {
  constructor() {
    console.log("MockGitDataService instance created");
  }

  // Mock commit history
  private mockCommits: GitLogEntry[] = [
    {
      hash: "abc123456789",
      subject: "Implement new file picker UI",
      refs: ["HEAD", "origin/main", "refs/heads/feature/file-picker"],
    },
    {
      hash: "def987654321",
      subject: "Add range picker component and improve styling",
      refs: [
        "origin/feature/range-picker",
        "refs/heads/feature/ui-improvements",
        "refs/remotes/origin/dev",
      ],
    },
    {
      hash: "ghi456789123",
      subject: "Fix styling issues in navigation and add responsive design",
      refs: ["refs/heads/hotfix/styling", "refs/tags/v1.2.0"],
    },
    {
      hash: "jkl789123456",
      subject: "Initial commit",
      refs: ["sketch-base"],
    },
  ];

  // Mock diff files for various scenarios
  private mockDiffFiles: GitDiffFile[] = [
    {
      path: "src/components/FilePicker.js",
      old_path: "",
      status: "A",
      new_mode: "100644",
      old_mode: "000000",
      old_hash: "0000000000000000000000000000000000000000",
      new_hash: "def0123456789abcdef0123456789abcdef0123",
      additions: 54,
      deletions: 0,
    },
    {
      path: "src/components/RangePicker.js",
      old_path: "",
      status: "A",
      new_mode: "100644",
      old_mode: "000000",
      old_hash: "0000000000000000000000000000000000000000",
      new_hash: "cde0123456789abcdef0123456789abcdef0123",
      additions: 32,
      deletions: 0,
    },
    {
      path: "src/components/App.js",
      old_path: "",
      status: "M",
      new_mode: "100644",
      old_mode: "100644",
      old_hash: "abc0123456789abcdef0123456789abcdef0123",
      new_hash: "bcd0123456789abcdef0123456789abcdef0123",
      additions: 15,
      deletions: 3,
    },
    {
      path: "src/components/DialogPicker.js",
      old_path: "src/components/FilePicker.js",
      status: "C85",
      new_mode: "100644",
      old_mode: "100644",
      old_hash: "def0123456789abcdef0123456789abcdef0123",
      new_hash: "hij0123456789abcdef0123456789abcdef0123",
      additions: 8,
      deletions: 2,
    },
    {
      path: "src/components/RangeSelector.js", 
      old_path: "src/components/RangePicker.js",
      status: "R95",
      new_mode: "100644",
      old_mode: "100644",
      old_hash: "cde0123456789abcdef0123456789abcdef0123",
      new_hash: "klm0123456789abcdef0123456789abcdef0123",
      additions: 5,
      deletions: 3,
    },
    {
      path: "src/styles/main.css",
      old_path: "",
      status: "M",
      new_mode: "100644",
      old_mode: "100644",
      old_hash: "fgh0123456789abcdef0123456789abcdef0123",
      new_hash: "ghi0123456789abcdef0123456789abcdef0123",
      additions: 25,
      deletions: 8,
    },
  ];

  // Mock file content for different files and commits
  private appJSOriginal = `function App() {
  return (
    <div className="app">
      <header>
        <h1>Git Diff Viewer</h1>
      </header>
      <main>
        <p>Select a file to view differences</p>
      </main>
    </div>
  );
}`;

  private appJSModified = `function App() {
  const [files, setFiles] = useState([]);
  const [selectedFile, setSelectedFile] = useState(null);
  
  // Load commits and files
  useEffect(() => {
    // Code to load commits would go here
    // setCommits(...);
  }, []);
  
  return (
    <div className="app">
      <header>
        <h1>Git Diff Viewer</h1>
      </header>
      <main>
        <FilePicker files={files} onFileSelect={setSelectedFile} />
        <div className="diff-view">
          {selectedFile ? (
            <div>Diff view for {selectedFile.path}</div>
          ) : (
            <p>Select a file to view differences</p>
          )}
        </div>
      </main>
    </div>
  );
}`;

  private filePickerJS = `function FilePicker({ files, onFileSelect }) {
  const [selectedIndex, setSelectedIndex] = useState(0);
  
  useEffect(() => {
    // Reset selection when files change
    setSelectedIndex(0);
    if (files.length > 0) {
      onFileSelect(files[0]);
    }
  }, [files, onFileSelect]);
  
  const handleNext = () => {
    if (selectedIndex < files.length - 1) {
      const newIndex = selectedIndex + 1;
      setSelectedIndex(newIndex);
      onFileSelect(files[newIndex]);
    }
  };
  
  const handlePrevious = () => {
    if (selectedIndex > 0) {
      const newIndex = selectedIndex - 1;
      setSelectedIndex(newIndex);
      onFileSelect(files[newIndex]);
    }
  };
  
  return (
    <div className="file-picker">
      <select value={selectedIndex} onChange={(e) => {
        const index = parseInt(e.target.value, 10);
        setSelectedIndex(index);
        onFileSelect(files[index]);
      }}>
        {files.map((file, index) => (
          <option key={file.path} value={index}>
            {file.status} {file.path}
          </option>
        ))}
      </select>
      
      <div className="navigation-buttons">
        <button 
          onClick={handlePrevious} 
          disabled={selectedIndex === 0}
        >
          Previous
        </button>
        <button 
          onClick={handleNext} 
          disabled={selectedIndex === files.length - 1}
        >
          Next
        </button>
      </div>
    </div>
  );
}`;

  private rangePickerJS = `function RangePicker({ commits, onRangeChange }) {
  const [rangeType, setRangeType] = useState('range');
  const [startCommit, setStartCommit] = useState(commits[0]);
  const [endCommit, setEndCommit] = useState(commits[commits.length - 1]);

  const handleTypeChange = (e) => {
    setRangeType(e.target.value);
    if (e.target.value === 'single') {
      onRangeChange({ type: 'single', commit: startCommit });
    } else {
      onRangeChange({ type: 'range', from: startCommit, to: endCommit });
    }
  };

  return (
    <div className="range-picker">
      <div className="range-type-selector">
        <label>
          <input 
            type="radio" 
            value="range" 
            checked={rangeType === 'range'} 
            onChange={handleTypeChange} 
          />
          Commit Range
        </label>
        <label>
          <input 
            type="radio" 
            value="single" 
            checked={rangeType === 'single'} 
            onChange={handleTypeChange} 
          />
          Single Commit
        </label>
      </div>
    </div>
  );
}`;

  private dialogPickerJS = `function DialogPicker({ files, onFileSelect, onClose }) {
  const [selectedIndex, setSelectedIndex] = useState(0);
  const [showDialog, setShowDialog] = useState(false);
  
  // Similar to FilePicker but with modal dialog functionality
  useEffect(() => {
    setSelectedIndex(0);
    if (files.length > 0) {
      onFileSelect(files[0]);
    }
  }, [files, onFileSelect]);
  
  return (
    <div className="dialog-picker">
      <button onClick={() => setShowDialog(true)}>
        Open File Dialog
      </button>
      {showDialog && (
        <div className="modal-overlay" onClick={() => setShowDialog(false)}>
          <div className="modal-content" onClick={(e) => e.stopPropagation()}>
            <h3>Select File</h3>
            <select value={selectedIndex} onChange={(e) => {
              const index = parseInt(e.target.value, 10);
              setSelectedIndex(index);
              onFileSelect(files[index]);
            }}>
              {files.map((file, index) => (
                <option key={file.path} value={index}>
                  {file.status} {file.path}
                </option>
              ))}
            </select>
            <div className="modal-buttons">
              <button onClick={() => setShowDialog(false)}>Close</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}`;

  private rangeSelectorJS = `function RangeSelector({ commits, onRangeChange, allowCustomRange = true }) {
  const [rangeType, setRangeType] = useState('range');
  const [startCommit, setStartCommit] = useState(commits[0]);
  const [endCommit, setEndCommit] = useState(commits[commits.length - 1]);
  const [customRange, setCustomRange] = useState('');

  const handleTypeChange = (e) => {
    setRangeType(e.target.value);
    if (e.target.value === 'single') {
      onRangeChange({ type: 'single', commit: startCommit });
    } else if (e.target.value === 'custom' && customRange) {
      onRangeChange({ type: 'custom', range: customRange });
    } else {
      onRangeChange({ type: 'range', from: startCommit, to: endCommit });
    }
  };

  return (
    <div className="range-selector">
      <div className="range-type-selector">
        <label>
          <input 
            type="radio" 
            value="range" 
            checked={rangeType === 'range'} 
            onChange={handleTypeChange} 
          />
          Commit Range
        </label>
        <label>
          <input 
            type="radio" 
            value="single" 
            checked={rangeType === 'single'} 
            onChange={handleTypeChange} 
          />
          Single Commit
        </label>
        {allowCustomRange && (
          <label>
            <input 
              type="radio" 
              value="custom" 
              checked={rangeType === 'custom'} 
              onChange={handleTypeChange} 
            />
            Custom Range
          </label>
        )}
      </div>
      {rangeType === 'custom' && (
        <input 
          type="text" 
          placeholder="Enter custom range (e.g., HEAD~5..HEAD)"
          value={customRange}
          onChange={(e) => setCustomRange(e.target.value)}
        />
      )}
    </div>
  );
}`;

  private mainCSSOriginal = `body {
  font-family: sans-serif;
  margin: 0;
  padding: 0;
}

.app {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

header {
  margin-bottom: 20px;
}

h1 {
  color: #333;
}`;

  private mainCSSModified = `body {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  margin: 0;
  padding: 0;
  background-color: #f5f5f5;
}

.app {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

header {
  margin-bottom: 20px;
  border-bottom: 1px solid #ddd;
  padding-bottom: 10px;
}

h1 {
  color: #333;
}

.file-picker {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 20px;
}

.file-picker select {
  flex: 1;
  padding: 8px;
  border-radius: 4px;
  border: 1px solid #ddd;
}

.navigation-buttons {
  display: flex;
  gap: 8px;
}

button {
  padding: 8px 12px;
  background-color: #4a7dfc;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}`;

  async getCommitHistory(initialCommit?: string): Promise<GitLogEntry[]> {
    console.log(
      `[MockGitDataService] Getting commit history from ${initialCommit || "beginning"}`,
    );

    // If initialCommit is provided, return commits from that commit to HEAD
    if (initialCommit) {
      const startIndex = this.mockCommits.findIndex(
        (commit) => commit.hash === initialCommit,
      );
      if (startIndex >= 0) {
        return this.mockCommits.slice(0, startIndex + 1);
      }
    }

    return [...this.mockCommits];
  }

  async getDiff(from: string, to: string): Promise<GitDiffFile[]> {
    console.log(`[MockGitDataService] Getting diff from ${from} to ${to}`);

    return [...this.mockDiffFiles];
  }

  async getCommitDiff(commit: string): Promise<GitDiffFile[]> {
    console.log(`[MockGitDataService] Getting diff for commit ${commit}`);

    // Return a subset of files for specific commits
    if (commit === "abc123456789") {
      return this.mockDiffFiles.slice(0, 2);
    } else if (commit === "def987654321") {
      return this.mockDiffFiles.slice(1, 3);
    }

    // For other commits, return all files
    return [...this.mockDiffFiles];
  }

  async getFileContent(fileHash: string): Promise<string> {
    console.log(
      `[MockGitDataService] Getting file content for hash: ${fileHash}`,
    );

    // Return different content based on the file hash
    if (fileHash === "bcd0123456789abcdef0123456789abcdef0123") {
      return this.appJSModified;
    } else if (fileHash === "abc0123456789abcdef0123456789abcdef0123") {
      return this.appJSOriginal;
    } else if (fileHash === "def0123456789abcdef0123456789abcdef0123") {
      return this.filePickerJS;
    } else if (fileHash === "cde0123456789abcdef0123456789abcdef0123") {
      return this.rangePickerJS;
    } else if (fileHash === "hij0123456789abcdef0123456789abcdef0123") {
      return this.dialogPickerJS;
    } else if (fileHash === "klm0123456789abcdef0123456789abcdef0123") {
      return this.rangeSelectorJS;
    } else if (fileHash === "ghi0123456789abcdef0123456789abcdef0123") {
      return this.mainCSSModified;
    } else if (fileHash === "fgh0123456789abcdef0123456789abcdef0123") {
      return this.mainCSSOriginal;
    }

    // Return empty string for unknown file hashes
    return "";
  }

  async getBaseCommitRef(): Promise<string> {
    console.log("[MockGitDataService] Getting base commit ref");

    // Find the commit with the sketch-base ref
    const baseCommit = this.mockCommits.find(
      (commit) => commit.refs && commit.refs.includes("sketch-base"),
    );

    if (baseCommit) {
      return baseCommit.hash;
    }

    // Fallback to the last commit in our list
    return this.mockCommits[this.mockCommits.length - 1].hash;
  }

  // Helper to simulate network delay
  private delay(ms: number): Promise<void> {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }

  async getWorkingCopyContent(filePath: string): Promise<string> {
    console.log(
      `[MockGitDataService] Getting working copy content for path: ${filePath}`,
    );

    // Return different content based on the file path
    if (filePath === "src/components/App.js") {
      return this.appJSModified;
    } else if (filePath === "src/components/FilePicker.js") {
      return this.filePickerJS;
    } else if (filePath === "src/components/RangePicker.js") {
      return this.rangePickerJS;
    } else if (filePath === "src/components/DialogPicker.js") {
      return this.dialogPickerJS;
    } else if (filePath === "src/components/RangeSelector.js") {
      return this.rangeSelectorJS;
    } else if (filePath === "src/styles/main.css") {
      return this.mainCSSModified;
    }

    // Return empty string for unknown file paths
    return "";
  }

  async getUnstagedChanges(from: string = "HEAD"): Promise<GitDiffFile[]> {
    console.log(`[MockGitDataService] Getting unstaged changes from ${from}`);

    // Create a new array of files with 0000000... as the new hashes
    // to simulate unstaged changes
    return this.mockDiffFiles.map((file) => ({
      ...file,
      new_hash: "0000000000000000000000000000000000000000",
    }));
  }

  async saveFileContent(filePath: string, content: string): Promise<void> {
    console.log(
      `[MockGitDataService] Saving file content for path: ${filePath}`,
    );
    // Simulate a network delay
    await this.delay(500);
    // In a mock implementation, we just log the save attempt
    console.log(
      `File would be saved: ${filePath} (${content.length} characters)`,
    );
    // Return void as per interface
  }
}
