import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';

import './App.css';
import TextField from '@mui/material/TextField';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import { apiFetch } from './api';

type AudioDevice = {
  index: number;
  name: string;
  default_sample_rate: number;
  channels: number;
};

type Settings = {
  http_port: number;
  input_device: AudioDevice;
  output_device: AudioDevice;
  recording_length: number;
  save_path: string;
};

const defaultSettings: Settings = {
  http_port: 0,
  input_device: { index: 0, name: '', default_sample_rate: 0, channels: 0 },
  output_device: { index: 0, name: '', default_sample_rate: 0, channels: 0 },
  recording_length: 0,
  save_path: '',
};

async function fetchAudioDevices(
  type: 'input' | 'output',
): Promise<AudioDevice[]> {
  // Replace with actual backend call
  // Example: return window.api.getAudioDevices();
  return apiFetch(`device/list?device_type=${type}`)
    .then((res) => res.json())
    .then((data) => data.devices as AudioDevice[])
    .catch((error) => {
      console.error('Error fetching audio devices:', error);
      return [];
    });
}

async function fetchSettings(): Promise<Settings> {
  // Replace with actual backend call
  // Example: return window.api.getAudioDevices();
  console.log('Fetching settings from backend...');
  return apiFetch('settings')
    .then((res) => res.json())
    .then((data) => data.settings as Settings)
    .catch((error) => {
      console.error('Error fetching settings:', error);
      return defaultSettings;
    });
}

const sendSettingsToBackend = async (settings: Settings) => {
  // Replace with actual backend call
  // Example: window.api.updateSettings(settings);
  console.log('Settings updated:', settings);
  await apiFetch('settings/update', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ settings }),
  })
    .then((res) => res.json())
    .then((data) => {
      console.log('Settings update response:', data);
      if (data.status === 'success') {
        window.audio.restartService();
      }
      return data;
    })
    .catch((error) => {
      console.error('Error updating settings:', error);
    });
};

export default function SettingsPage() {
  const [settings, setSettings] = useState<Settings>(defaultSettings);
  const [inputDevices, setInputDevices] = useState<AudioDevice[]>([]);
  const [outputDevices, setOutputDevices] = useState<AudioDevice[]>([]);
  const navigate = useNavigate();

  useEffect(() => {
    fetchSettings()
      .then((fetchedSettings) => {
        console.log('Fetched settings:', fetchedSettings);
        setSettings(fetchedSettings);
        return null;
      })
      .then(() => {
        return fetchAudioDevices('input');
      })
      .then((devices) => {
        setInputDevices(devices);
        // console.log('Input devices:', devices);
        return fetchAudioDevices('output');
      })
      .then((devices) => {
        setOutputDevices(devices);

        // console.log('Output devices:', devices);
        return devices;
      })
      .catch((error) => {
        console.error('Error fetching audio devices:', error);
      });
  }, []);

  useEffect(() => {}, [settings]);

  const handleChange = () => {
    sendSettingsToBackend(settings);
    // const { name, value } = e.target;
    // setSettings((prev) => ({
    //   ...prev,
    //   [name]: value,
    // }));
  };

  const handleFolderChange = async () => {
    // Replace with actual folder picker
    // Example: const folder = await window.api.selectFolder();
    // const folder = window.prompt(
    //   'Enter output folder path:',
    //   settings.outputFolder,
    // );
    // if (folder !== null) {
    //   setSettings((prev) => ({
    //     ...prev,
    //     outputFolder: folder,
    //   }));
    // }
  };

  return (
    <div className="min-w-screen min-h-screen bg-midnight text-offwhite flex items-center justify-center relative">
      <div className="w-3/4 min-w-[600px] max-w-[800px] self-start flex flex-col font-sans bg-midnight text-offwhite p-6 rounded-lg relative">
        {/* X Close Button */}
        <button
          type="button"
          className="absolute top-6 right-6 text-3xl font-bold text-offwhite bg-transparent hover:text-plumDark"
          aria-label="Close settings"
          onClick={() => navigate('/')}
        >
          ×
        </button>
        <span className="text-2xl font-bold mb-4">Settings</span>
        <div className="mb-4 flex justify-between">
          <span>HTTP Port:</span>
          <TextField
            variant="standard"
            type="text"
            name="httpPort"
            value={settings.http_port}
            onBlur={() => handleChange()}
            onChange={(e) => {
              if (!Number.isNaN(Number(e.target.value))) {
                setSettings((prev) => ({
                  ...prev,
                  http_port: Number(e.target.value),
                }));
              }
            }}
            className="ml-2 text-white w-[150px]"
          />
        </div>
        <div className="mb-4 flex justify-between">
          <span>Input Audio Device:</span>
          <Select
            variant="standard"
            name="inputDevice"
            value={settings.input_device.index}
            onChange={(e) => {
              const newDevice = inputDevices.find(
                (dev) => dev.index === Number(e.target.value),
              );
              console.log('Selected input device index:', newDevice);
              if (newDevice) {
                setSettings((prev) => ({
                  ...prev,
                  input_device: newDevice,
                }));
                sendSettingsToBackend({
                  ...settings,
                  input_device: newDevice,
                });
              }
            }}
            className="ml-2 w-64"
          >
            {inputDevices.map((dev) => (
              <MenuItem key={dev.index} value={dev.index}>
                {dev.name}
              </MenuItem>
            ))}
          </Select>
        </div>
        <div className="mb-4 flex justify-between">
          <span>Output Audio Device:</span>
          <Select
            variant="standard"
            name="outputDevice"
            value={settings.output_device.index}
            onChange={(e) => {
              const newDevice = outputDevices.find(
                (dev) => dev.index === Number(e.target.value),
              );
              if (newDevice) {
                setSettings((prev) => ({
                  ...prev,
                  output_device: newDevice,
                }));
                sendSettingsToBackend({
                  ...settings,
                  output_device: newDevice,
                });
              }
            }}
            className="ml-2 w-64"
          >
            {outputDevices.map((dev) => (
              <MenuItem key={dev.index} value={dev.index}>
                {dev.name}
              </MenuItem>
            ))}
          </Select>
        </div>
        <div className="mb-4 flex justify-between">
          <span>Recording Length (seconds):</span>
          <TextField
            variant="standard"
            type="text"
            name="recordingLength"
            value={settings.recording_length}
            onChange={(e) => {
              if (!Number.isNaN(Number(e.target.value))) {
                setSettings((prev) => ({
                  ...prev,
                  recording_length: Number(e.target.value),
                }));
              }
            }}
            onBlur={() => handleChange()}
            className="ml-2 w-[150px]"
          />
        </div>
        <div className="mb-4 flex justify-between">
          <span>Clip Output Folder:</span>
          <div className="flex justify-end">
            <TextField
              variant="standard"
              type="text"
              name="savePath"
              value={settings.save_path}
              className="ml-2 w-[300px]"
            />
            <button
              type="button"
              onClick={handleFolderChange}
              className="ml-2 px-3 py-1 rounded bg-plumDark text-offwhite hover:bg-plum"
            >
              ...
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
