import { client } from "./client.mjs";
import { html, create, styled } from "./misc.mjs";

const default_ssml = `
<speak version="0.1">
  <voice spk="Bob" seed="-1" style="narration-relaxed">
    这里是一个简单的 SSML 示例。 
  </voice>
</speak>
`.trim();

const useStore = create((set, get) => ({
  params: {
    ssml: default_ssml,
    format: "mp3",
  },
  setParams: (params) => set({ params }),

  loading: false,

  /**
   * @type {Array<{ id: number, params: { ssml: string; format: string }, url: string }>}
   */
  history: [],
  setHistory: (history) => set({ history }),
}));

const SSMLFormContainer = styled.div`
  display: flex;
  flex-direction: column;

  textarea {
    width: 100%;
    height: 10rem;
    margin-bottom: 1rem;

    min-height: 10rem;

    resize: vertical;
  }

  button {
    padding: 0.5rem 1rem;
    background-color: #007bff;
    color: white;
    border: none;
    cursor: pointer;
  }

  button:hover {
    background-color: #0056b3;
  }

  button:disabled {
    background-color: #6c757d;
    cursor: not-allowed;
  }

  fieldset {
    margin-top: 1rem;
    padding: 1rem;
    border: 1px solid #333;
  }

  legend {
    font-weight: bold;
  }

  label {
    display: block;
    margin-bottom: 0.5rem;
  }

  select,
  input[type="range"],
  input[type="number"] {
    width: 100%;
    margin-top: 0.25rem;
  }

  input[type="range"] {
    width: calc(100% - 2rem);
  }

  input[type="number"] {
    width: calc(100% - 2rem);
    padding: 0.5rem;
  }

  input[type="text"] {
    width: 100%;
    padding: 0.5rem;
  }

  audio {
    margin-top: 1rem;
  }

  textarea,
  input,
  select {
    background-color: #333;
    color: white;
    border: 1px solid #333;
    border-radius: 0.25rem;
    padding: 0.5rem;
  }

  .ssml-body {
    display: flex;
    gap: 1rem;
  }

  table {
    width: 100%;
    border-collapse: collapse;
  }

  th,
  td {
    padding: 0.5rem;
    border: 1px solid #333;
  }

  th {
    background-color: #333;
    color: white;
  }

  .btn-danger {
    background-color: #dc3545;
    color: white;
    border: none;
    cursor: pointer;
  }

  .btn-danger:hover {
    background-color: #bd2130;
  }
`;

const SSMLOptions = () => {
  const { params, setParams } = useStore();
  return html`
    <fieldset style="flex: 2">
      <legend>Options</legend>
      <label>
        Format
        <select
          value=${params.format}
          onChange=${(e) => setParams({ ...params, format: e.target.value })}
        >
          <option value="mp3">MP3</option>
          <option value="wav">WAV</option>
        </select>
      </label>
    </fieldset>
  `;
};

const SSMLHistory = () => {
  const { history } = useStore();
  return html`
    <fieldset style="flex: 5">
      <legend>History</legend>

      <table>
        <thead>
          <tr>
            <th>index</th>
            <th>SSML</th>
            <th>Audio</th>
          </tr>
        </thead>
        <tbody>
          ${[...history].reverse().map(
            (item) => html`
              <tr key=${item.id}>
                <td>${item.id}</td>
                <td>
                  <textarea
                    readonly
                    style="width: 100%; height: 5rem; resize: none;"
                  >
                    ${item.params.ssml}
                  </textarea
                  >
                </td>
                <td>
                  <audio controls>
                    <source
                      src=${item.url}
                      type="audio/${item.params.format}"
                    />
                  </audio>
                </td>
              </tr>
            `
          )}
        </tbody>
      </table>
    </fieldset>
  `;
};

let generate_index = 0;

const SSMLForm = () => {
  const { params, setParams, loading } = useStore();
  const request = async () => {
    useStore.set({ loading: true });
    try {
      const blob = await client.synthesizeSSML(params);
      const blob_url = URL.createObjectURL(blob);
      useStore.set({
        history: [
          ...useStore.get().history,
          {
            id: generate_index++,
            params,
            url: blob_url,
          },
        ],
      });
    } finally {
      useStore.set({ loading: false });
    }
  };
  return html`
    <${SSMLFormContainer}>
      <textarea
        placeholder="Enter SSML here..."
        value=${params.ssml}
        onInput=${(e) => setParams({ ...params, ssml: e.target.value })}
      />
      <div>
        <button onClick=${request} disabled=${!params.ssml || loading}>
          Submit
        </button>
        <button
          class="btn btn-danger"
          onClick=${() => {
            useStore.set({ history: [] });
          }}
          disabled=${loading}
        >
          Clear History
        </button>
      </div>

      <div class="ssml-body">
        <${SSMLOptions} />
        <${SSMLHistory} />
      </div>
    <//>
  `;
};

const SSMLPageContainer = styled.div`
  display: flex;
  flex-direction: column;
  height: 100%;
`;

export const SSMLPage = () => {
  return html` <${SSMLPageContainer}>
    <${SSMLForm} />
  <//>`;
};